16

I'm using the Microsoft Visual Studio 2019 compiler (cl.exe), and it is rejecting some code accepted by both Clang and GCC, related to using enums as template parameters, where the templates are specialized for particular enum values.

enum Foo {
    Bar,
    Baz
};

template<enum Foo = Bar> class Clazz {

};

template<> class Clazz<Baz> {

};

The VC++ compiler reports several errors on the template specialization:

<source>(10): error C2440: 'specialization': cannot convert from 'Foo' to 'Foo'
<source>(10): note: Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)

This code is accepted without errors by both Clang and GCC. Is this a bug with VC++?

Replacing the 'enum Foo' in the template declaration with just 'int' causes the errors to go away. However, this is not an acceptable answer, as I'm trying to port a large code base over to VC++.

2
  • 1
    Looks like a compiler bug to me. I see nutin' wrong. Commented Aug 22, 2019 at 14:53
  • Have you try template<Foo = Bar> class Clazz {? Maybe Msvc introduces another enum named Foo. Commented Aug 22, 2019 at 14:58

2 Answers 2

4

Your code will compile if you use the Standards Conformance Mode compiler option /permissive- to specify standards-conforming compiler behavior.

You can add that option on the command line or in the "Project property page -> C/C++ -> Language -> Conformance mode".

Sign up to request clarification or add additional context in comments.

3 Comments

This causes the compiler to accept the code, but it looks like internally it's still treating all enums s equivalent. For example, it rejects this snippet: godbolt.org/z/XxUjDI
@HarryWagstaff You might have found a real compiler bug. If you have time you should file a report to the VS Dev Community.
It still happens even if /permissive- is set if you're using C++14 in VS2022
0

You are missing a T:

template<enum Foo T = Bar> class Clazz {

Or have an extra enum:

template<Foo = Bar> class Clazz {

This second one is much nicer, thanks François.

2 Comments

I wouldn't use T as value in template though :-)
template<Foo = Bar> class Clazz also fixes the problem. Template arguments don't need names, so I'm not sure what is happening here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.