O que é esta construção: template <int> void funcName (int i)?

Oct 02 2020

Eu acidentalmente cometi um erro ao codificar uma especialização de função de modelo, e a construção resultante passou na compilação com VS17. (A terceira construção no código incluído abaixo)

Esta é uma construção válida? Como eu chamaria essa função?

template <class T> void tempfunc(T t)
{
    cout << "Generic Template Version\n";
}

template <>
void tempfunc<int>(int i) {
    cout << "Template Specialization Version\n";
}

template <int> void tempfunc(int i)
{
    cout << "Coding Mistake Version\n";
}

Não fui capaz de chamar a terceira construção.

Respostas

6 cigien Oct 02 2020 at 02:15

Sim, é uma construção válida. É uma sobrecarga de modelo, que é modelada em um parâmetro de modelo não-tipo do tipo int.

Você pode chamá-lo assim:

tempfunc<42>(42);

Observe que as chamadas sem a sintaxe do modelo ainda chamarão as versões que são modeladas em um parâmetro de tipo:

tempfunc(42);   // calls specialization
tempfunc(true); // calls primary 

Aqui está uma demonstração

3 RSahu Oct 02 2020 at 02:15

template os parâmetros são de dois tipos - parâmetros de tipo e parâmetros sem tipo.

Quando você usa

template <class T> void tempfunc(T t) { ... }

o templateparâmetro é um parâmetro de tipo. Para usar esse modelo, o tipo deve ser deduzido ou explicitamente fornecido.

Quando você usa

template <int> void tempfunc(int i) { ... }

o templateparâmetro é um parâmetro sem tipo. Pelo que eu sei, o valor de um parâmetro sem tipo não pode ser deduzido. Ele deve ser fornecido explicitamente.

O último templateusa um parâmetro não-tipo. O valor com o qual pode ser chamado deve ser do tipo int. Exemplo de invocações:

tempfunc<0>(20);
tempfunc<999>(34);