Skip to content

Commit 95dc0fb

Browse files
authored
Update C2993
1 parent c192538 commit 95dc0fb

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed
Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: "Learn more about: Compiler Error C2993"
33
title: "Compiler Error C2993"
4-
ms.date: "11/04/2016"
4+
ms.date: "10/03/2023"
55
f1_keywords: ["C2993"]
66
helpviewer_keywords: ["C2993"]
77
ms.assetid: 4ffd2b78-654b-46aa-95a6-b62101cf91c8
@@ -10,34 +10,50 @@ ms.assetid: 4ffd2b78-654b-46aa-95a6-b62101cf91c8
1010

1111
'identifier' : illegal type for non-type template parameter 'parameter'
1212

13-
You cannot declare a template with a structure or union argument. Use pointers to pass structures and unions as template parameters.
13+
You cannot declare a template with a structure, class or union argument. However, pointers can be used in place of those types as template parameters. Since C++20, structure, class or unions can be used as non-type template parameters.
1414

1515
The following sample generates C2993:
1616

1717
```cpp
1818
// C2993.cpp
19-
// compile with: /c
20-
// C2993 expected
21-
struct MyStruct {
22-
int a;char b;
23-
};
19+
// compile with: /c /std:c++17
20+
struct MyStruct {};
2421

25-
template <class T, struct MyStruct S> // C2993
22+
template <class T, MyStruct S> // C2993
23+
class MyClass1 {};
2624

27-
// try the following line instead
28-
// template <class T, struct MyStruct * S>
29-
class CMyClass {};
25+
template <class T, MyStruct* S> // OK
26+
class MyClass2 {};
3027
```
3128
32-
This error will also be generated as a result of compiler conformance work that was done in Visual Studio .NET 2003: floating point non-type template parameters no longer allowed. The C++ standard does not allow floating point non-type template parameters.
29+
> [!NOTE]
30+
> The sample above no longer emits C2993 since MSVC v19.26 and instead shows C7592.
31+
32+
With C++17 and earlier, you cannot have floating point non-type template parameters. Since C++20, floating point non-type template parameters are allowed as with literal class types.
3333
34-
If it is a function template, use a function argument to pass in the floating point non-type template parameter (this code will be valid in the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++). If it is a class template, there is no easy workaround.
34+
If it is a function template, use a function argument to pass in the floating point non-type template parameter.
3535
3636
```cpp
3737
// C2993b.cpp
38+
// compile with: /c /std:c++17
39+
template<class T, float F> // C2993
40+
void func1(T t) {}
41+
42+
template<class T> // OK
43+
void func2(T t, float F) {}
44+
```
45+
46+
> [!NOTE]
47+
> The sample above no longer emits C2993 since MSVC v19.26 and instead shows C7592.
48+
49+
Non-type template parameters cannot be of rvalue reference type. Similarly, a parameter pack of such types are not allowed.
50+
51+
```cpp
52+
// C2993c.cpp
3853
// compile with: /c
39-
template<class T, float f> void func(T) {} // C2993
54+
template <int&& I> // C2993
55+
struct S1 {};
4056

41-
// OK
42-
template<class T> void func2(T, float) {}
57+
template <int&&... Is> // C2993
58+
struct S2 {};
4359
```

0 commit comments

Comments
 (0)