Sep 20, 2016

[C++] unscoped enum type promotion issue.

http://stackoverflow.com/a/35538979/1316609


A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different.

While these are equally as good, so the template/non-template tiebreaker comes in.
The first one is a function template;
the second one is a plain member function,
so the second one wins.
#include <iostream>

enum num : char {
    zero = '0',
    one = '1',
    two = '2',
    three = '3',
    four = '4',
    five = '5',
    six = '6'
};

int main()
{
    const char two = '2';
    std::cout << two << std::endl;
    std::cout << num::two;
    return 0;
}

Should print: 
2
2

----

15
down voteaccepted
This should actually go to the char overload now; unfortunately none of the compilers at issue implement DR 1601.
A prvalue of an unscoped enumeration type whose underlying type is fixed ([dcl.enum]) can be converted to a prvalue of its underlying type.
This means num can be promoted to char.
Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type.
So num can be promoted to int, too.
The relevant candidates are:
template <class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
                                        char ch );
template<class charT, class Traits>
basic_ostream<charT, Traits>& basic_ostream<charT, Traits>::operator<<(int);
For both candidates, the first argument is an identity conversion and the second is a promotion. Both num to char and num to int have promotion rank.
Pre-DR1601, these are equally as good, so the template/non-template tiebreaker comes in. The first one is a function template; the second one is a plain member function, so the second one wins.
DR1601 added a rule that says:
A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different.
This means that num to char is now better than num to int, so the first overload is now a better match and should be selected.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.