编译器错误 C2993

“identifier”:非类型模板参数“parameter”的类型非法

  • 在 C++20 之前,不能使用结构、类或联合参数声明模板。 可以使用指针代替这些类型作为模板参数。
  • 从 C++20 开始,结构、类或联合可以用作非类型模板参数。 非类型模板参数不能是 rvalue 引用类型或 rvalue 类型的参数包。

以下示例生成 C2993:

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

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

在 MSVC 19.26 之前,以下代码会发出 C2993。 它现在发出 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 {};

在 C++17 及更低版本中,不能使用浮点非类型模板参数。 从 C++20 开始,允许使用浮点非类型模板参数。 使用函数参数将浮点非类型模板参数传递给函数模板。

在 MSVC 19.26 之前,以下代码会发出 C2993。 它现在发出 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) {}