Erro do compilador C2993

'identifier' : tipo ilegal para parâmetro de modelo de não tipo 'parâmetro'

  • Antes do C++20, você não pode declarar um modelo com um argumento de estrutura, classe ou união. Os ponteiros podem ser usados no lugar desses tipos como parâmetros de modelo.
  • Desde o C++20, estrutura, classe ou uniões podem ser usadas como parâmetros de modelo que não sejam do tipo. Um parâmetro de modelo que não seja de tipo não pode ser um tipo de referência rvalue ou um parameter pack de tipos rvalue.

O seguinte exemplo gera o erro C2993:

// compile with: /c and /std:c++17
template <int&& I>   // C2993
struct S1 {};

template <int&&... Is>   // C2993
struct S2 {};

Antes do MSVC 19.26, o código a seguir emitia C2993. Ele agora emite C7582:

// compile with: /c /std:c++17
struct MyStruct {};

template <class T, MyStruct S>   // Was C2993 prior to MSVC 19.26. Now emits C7582.
class MyClass1 {};

template <class T, MyStruct* S>   // OK
class MyClass2 {};

Com o C++17 e versões anteriores, você não pode ter parâmetros de modelo de ponto flutuante que não sejam de tipo. Desde o C++20, parâmetros de modelo de ponto flutuante não tipo são permitidos. Use um argumento de função para passar o parâmetro de modelo de ponto flutuante que não é de tipo para modelos de função.

Antes do MSVC 19.26, o código a seguir emitia C2993. Ele agora emite C7582:

// C2993b.cpp
// compile with: /c /std:c++17
template<class T, float F>   // Was C2993 prior to MSVC 19.26. Now emits C7592
void func1(T t) {}

template<class T>   // OK
void func2(T t, float F) {}