Skip to content

Commit beb5236

Browse files
authored
Merge pull request MicrosoftDocs#5074 from MicrosoftDocs/FromPublicMasterBranch
Confirm merge from FromPublicMasterBranch to main to sync with https://github.com/MicrosoftDocs/cpp-docs (branch main)
2 parents 7c6f107 + c61c9b4 commit beb5236

File tree

2 files changed

+62
-30
lines changed

2 files changed

+62
-30
lines changed

docs/error-messages/compiler-errors-1/compiler-error-c2061.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,54 @@ The compiler found an identifier where it wasn't expected. Make sure that `ident
1414

1515
An initializer may be enclosed by parentheses. To avoid this problem, enclose the declarator in parentheses or make it a **`typedef`**.
1616

17-
This error could also be caused when the compiler detects an expression as a class template argument; use [typename](../../cpp/typename.md) to tell the compiler it is a type.
17+
This error could also be caused when the compiler detects an expression as a class template argument; use [typename](../../cpp/typename.md) to tell the compiler it is a type, as shown in the following example:
1818

1919
The following sample generates C2061:
2020

2121
```cpp
2222
// C2061.cpp
23-
// compile with: /c
24-
template < A a > // C2061
25-
// try the following line instead
26-
// template < typename b >
27-
class c{};
23+
// compile with: /std:c++17
24+
25+
template <A a> // C2061
26+
class C1 {};
27+
28+
template <typename A a> // ok
29+
class C2 {};
30+
31+
template <typename T>
32+
class C3
33+
{
34+
// Both are valid since C++20
35+
using Type1 = T::Type; // C2061
36+
using Type2 = typename T::Type; // OK
37+
};
38+
39+
int main()
40+
{
41+
int x;
42+
unsigned a1 = alignof(x); // C2061
43+
unsigned a2 = alignof(int); // OK
44+
unsigned a3 = alignof(decltype(x)); // OK
45+
}
2846
```
2947

48+
To resolve the error with `template<A a> class C1{};`, use `template <typename a> class C1 {};`\
49+
To resolve the issue with `using Type1 = T::Type;`, use `using Type1 = typename T::Type;`\
50+
To resolve the issue with `alignof(x)`, replace the argument with the type of `x`. In this case, `int` or `decltype(x);`
51+
3052
C2061 can occur if you pass an instance name to [typeid](../../extensions/typeid-cpp-component-extensions.md):
3153

3254
```cpp
3355
// C2061b.cpp
3456
// compile with: /clr
35-
ref struct G {
57+
ref struct G
58+
{
3659
int i;
3760
};
3861

39-
int main() {
40-
G ^ pG = gcnew G;
62+
int main()
63+
{
64+
G ^pG = gcnew G;
4165
System::Type ^ pType = typeid<pG>; // C2061
4266
System::Type ^ pType2 = typeid<G>; // OK
4367
}
Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,51 @@
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"]
7-
ms.assetid: 4ffd2b78-654b-46aa-95a6-b62101cf91c8
87
---
98
# Compiler Error C2993
109

1110
'identifier' : illegal type for non-type template parameter 'parameter'
1211

13-
You cannot declare a template with a structure or union argument. Use pointers to pass structures and unions as template parameters.
12+
- 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.
13+
- 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.
1414

1515
The following sample generates C2993:
1616

1717
```cpp
18-
// C2993.cpp
19-
// compile with: /c
20-
// C2993 expected
21-
struct MyStruct {
22-
int a;char b;
23-
};
24-
25-
template <class T, struct MyStruct S> // C2993
26-
27-
// try the following line instead
28-
// template <class T, struct MyStruct * S>
29-
class CMyClass {};
18+
// compile with: /c and /std:c++17
19+
template <int&& I> // C2993
20+
struct S1 {};
21+
22+
template <int&&... Is> // C2993
23+
struct S2 {};
24+
```
25+
26+
Before MSVC 19.26, the following code emitted C2993. It now emits C7582:
27+
28+
```cpp
29+
// compile with: /c /std:c++17
30+
struct MyStruct {};
31+
32+
template <class T, MyStruct S> // Was C2993 prior to MSVC 19.26. Now emits C7582.
33+
class MyClass1 {};
34+
35+
template <class T, MyStruct* S> // OK
36+
class MyClass2 {};
3037
```
3138

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.
39+
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.
3340

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.
41+
Before MSVC 19.26, the following code emitted C2993. It now emits C7582:
3542

3643
```cpp
3744
// C2993b.cpp
38-
// compile with: /c
39-
template<class T, float f> void func(T) {} // C2993
45+
// compile with: /c /std:c++17
46+
template<class T, float F> // Was C2993 prior to MSVC 19.26. Now emits C7592
47+
void func1(T t) {}
4048

41-
// OK
42-
template<class T> void func2(T, float) {}
49+
template<class T> // OK
50+
void func2(T t, float F) {}
4351
```

0 commit comments

Comments
 (0)