Skip to content

Update C2993 #4747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 29 additions & 21 deletions docs/error-messages/compiler-errors-2/compiler-error-c2993.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,51 @@
---
description: "Learn more about: Compiler Error C2993"
title: "Compiler Error C2993"
ms.date: "11/04/2016"
ms.date: "10/03/2023"
f1_keywords: ["C2993"]
helpviewer_keywords: ["C2993"]
ms.assetid: 4ffd2b78-654b-46aa-95a6-b62101cf91c8
---
# Compiler Error C2993

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

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

```cpp
// C2993.cpp
// compile with: /c
// C2993 expected
struct MyStruct {
int a;char b;
};

template <class T, struct MyStruct S> // C2993

// try the following line instead
// template <class T, struct MyStruct * S>
class CMyClass {};
// 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:

```cpp
// 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 {};
```

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.
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.

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

```cpp
// C2993b.cpp
// compile with: /c
template<class T, float f> void func(T) {} // C2993
// 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) {}

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