Enable template promotion. Why does this work sometimes and not others?

After some time struggling with this, I see what is happening below, but I still do not understand why. When I compile the code, I get the specified error message (only). Note that one line above it is exactly the same type conversion, and it works fine. In addition, as soon as I call enums (struct B), everything works fine, and if the templates are not involved (test1 and test3), everything works fine.

Is this a compiler error (I am using VS 2010)? Or can someone point to the part of the spec that talks about this?

struct A { enum { VALUE1 }; enum { VALUE2 }; }; struct B { enum Enum1 { VALUE1 }; enum Enum2 { VALUE2 }; }; void foo(int x) { } template <typename T> void bar(T x) { } void test1() { foo(A::VALUE1); foo(A::VALUE2); } void test2() { bar(A::VALUE1); bar(A::VALUE2); // error C2664: 'bar' : cannot convert parameter 1 from '' to '' // Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast) } void test3() { foo(B::VALUE1); foo(B::VALUE2); } void test4() { bar(B::VALUE1); bar(B::VALUE2); } 
+4
source share
2 answers

The definition of test2 poorly formed in accordance with the 2003 standard, but in the 2011 standard. But I can’t imagine why the compiler will accept one statement, but not another.

C ++ 03 14.3.1 / 2, my emphasis:

A local type, a non-binding type, an unnamed type, or a type made up of any of these types should not be used as a template argument for a template type parameter.

C ++ 11 completely removed this paragraph and replaced it with an example that involves implicitly using an unnamed struct as an argument of a template type.

+2
source

I'm not sure, but it seems to me that with templates in VS you can only use types with names. For some reason, the VS compiler does not recognize that the enumeration is simply int, even if it does not have a name. This is why test4() without errors and test2() does not.

Edit:

I dig a little decorator and found this answer. So this is not a compiler error. In my opinion, this is a feature because it also checks to see if your code matches the standard ones. In fact, GCC (vesrion 4.3.4, 4.4.5) will not compile this code anyway

 test.cpp: In function 'void test2()': test.cpp:34: error: no matching function for call to 'bar(A::<anonymous enum>)' test.cpp:35: error: no matching function for call to 'bar(A::<anonymous enum>)' 

but GCC 4.7.3 does not have an error (with `-Wall -Wextra -pedantic) it only reports unused parameters, perhaps C ++ 0x is less structured with respect to unnamed types in templates

Edit2:

I found on the Microsoft Page that VS supports Local and Unnamed types as template arguments , so your code should work. So finally, this is VS error!

+1
source

Source: https://habr.com/ru/post/1485322/


All Articles