What does enum & # 8594; int is a better conversion than enum & # 8594; unsigned?

In the following code, f(int) overload is selected instead of f(unsigned) f(int) . Tested with clang 3.0 and gcc 4.8.

 enum E { }; E f(int); int f(unsigned); E e = f(E(0)); 

My reading of the standard makes me think that enum -> int and enum -> unsigned are identical standard conversion sequences that contain only an integral conversion.

[conv.integral] An rvalue of an enumeration type can be converted to an rvalue of an integer type.

According to [over.best.ics], the rank of a standard transformation sequence containing only an integral transformation is "Transformation".

[over.ics.rank] Two implicit conversion sequences of the same form are indistinguishable conversion sequences if one of the following rules is not applied: [...]

None of the above rules apply when comparing two standard conversion sequences.

What am I missing?

+7
c ++ language-lawyer overloading implicit-conversion
source share
1 answer

C ++ 11:

[conv.prom] / 3

The value of an unoccupied enumeration type whose base type is not fixed (7.2) can be converted to the prvalue of the first of the following types , which can represent all enumeration values ​​(i.e., values ​​in the range from b min to b max, as described in 7.2): int , unsigned int , long int , unsigned long int , long long int or unsigned long long int .

(emphasis mine)

Then [over.ics.rank] / 4:

Standard conversion sequences are ordered by rank: Exact match is a better conversion than Promotion, which is a better conversion than Conversion.

So, to allow overloading in the expression f(E(0)) for overloading E f(int); only integral promotion is required (from E to int , via [conv.prom]), which has a higher rank Integral Conversion for int f(unsigned); required int f(unsigned); (from E to unsigned via [conv.integral]).


For C ++ 03, the argument is the same, although the first quote is slightly different: [Conv.prom] / 2

A value of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to the rvalue of the first of the following types, which can represent all the values ​​of its base type: int , unsigned int , long or unsigned long .

[over.ics.rank] / 4 - the same thing.

+6
source share

All Articles