Compiler Error C2993
'identifier' : illegal type for non-type template parameter 'parameter'
- Prior to C++20, you cannot declare a template with a structure, class, or union argument. Pointers can be used in place of these types as template parameters.
- Since C++20, structure, class, or unions can be used as non-type template parameters. A non-type template parameter can't be a rvalue reference type or a parameter pack of rvalue types.
The following sample generates C2993:
// compile with: /c and /std:c++17
template <int&& I> // C2993
struct S1 {};
template <int&&... Is> // C2993
struct S2 {};
Before MSVC 19.26, the following code emitted C2993. It now emits 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 {};
With C++17 and earlier, you can't have floating point non-type template parameters. Since C++20, floating point non-type template parameters are allowed. Use a function argument to pass the floating point non-type template parameter to function templates.
Before MSVC 19.26, the following code emitted C2993. It now emits 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) {}