是什么让enum - > int比enum更好的转换 - > unsigned?

wil*_*llj 7 c++ overloading language-lawyer implicit-conversion

在以下代码中,f(int)选择重载而不是f(unsigned).用clang 3.0和gcc 4.8测试.

enum E
{
};

E f(int);
int f(unsigned);

E e = f(E(0));
Run Code Online (Sandbox Code Playgroud)

我对该标准的阅读使我认为enum -> int并且enum -> unsigned是相同的标准转换序列,它们都只包含整数转换.

[conv.integral]枚举类型的右值可以转换为整数类型的右值.

根据[over.best.ics],仅包含积分转换的标准转换序列的等级是"转换".

[over.ics.rank]两个相同形式的隐式转换序列是无法区分的转换序列,除非以下规则之一适用:[...]

在比较两个标准转换序列时,所提到的规则似乎都不适用.

我错过了什么?

dyp*_*dyp 6

C++ 11:

[conv.prom]/3

其基础类型未固定的无范围枚举类型的prvalue(7.2)可以转换为以下第一种类型的prvalue,它们可以表示枚举的所有值(即b min到b范围内的值)如在7.2节中描述最大): ,int,unsigned int,long int,unsigned long int,long long intunsigned long long int.

(强调我的)

然后,[over.ics.rank]/4:

标准转化顺序按其排名排序:完全匹配是比促销更好的转化,这是一种比转化更好的转化.

因此,对于在表达重载解析f(E(0)),过载E f(int);只需要一个积分促进(从Eint,通过[conv.prom]),其具有更高的秩所需的积分转换int f(unsigned);(从Eunsigned通过[conv.integral]).


对于C++ 03,论证是相同的,尽管第一个引用略有不同:[conv.prom]/2

型的一个rvalue wchar_t(3.9.1)或枚举类型(7.2)可以被转换为第一以下类型可以表示其基础类型的所有值的右值:int,unsigned int,long,或unsigned long.

[over.ics.rank]/4是一样的.

  • @willj它也有点反直觉,例如`char`将转换为`int`而不是`unsigned char`(或`short`)用于重载解析,对于相同的共振. (2认同)