Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes enum -> int a better conversion than enum -> unsigned?

In the following code, the overload f(int) is chosen instead of f(unsigned). 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 lead me to think that enum -> int and enum -> unsigned are identical standard conversion sequences that both 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 conversion sequence containing only an integral conversion is 'Conversion'.

[over.ics.rank] Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules apply: [...]

None of the rules mentioned seem to apply when comparing the two standard conversion sequences.

What am I missing?

like image 320
willj Avatar asked Jul 23 '13 19:07

willj


1 Answers

C++11:

[conv.prom]/3

A prvalue of an unscoped enumeration type whose underlying type is not fixed (7.2) can be converted to a prvalue of the first of the following types that can represent all the values of the enumeration (i.e., the values in the range 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 their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion.

So, for overload resolution on the expression f(E(0)), the overload E f(int); requires only an Integral Promotion (from E to int, via [conv.prom]), which has a higher rank the Integral Conversion required for int f(unsigned); (from E to unsigned via [conv.integral]).


For C++03, the argumentation is the same, though the first quote is slightly different: [conv.prom]/2

An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of its underlying type: int, unsigned int, long, or unsigned long.

[over.ics.rank]/4 is the same.

like image 143
dyp Avatar answered Nov 11 '22 08:11

dyp