7

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

enum E
{
};

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

E e = f(E(0));

我对标准的阅读使我认为这是相同的标准转换序列,它们都只包含一个积分转换enum -> intenum -> unsigned

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

根据[over.best.ics],仅包含整数转换的标准转换序列的等级是'Conversion'。

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

在比较两个标准转换序列时,上述规则似乎都不适用。

我错过了什么?

4

1 回答 1

6

C++11:

[conv.prom]/3

基础类型不固定(7.2)的无作用域枚举类型的纯右值可以转换为以下第一种类型的纯右值,该类型可以表示枚举的所有值(即范围 b min 到 b 中的值) 7.2 中描述的最大值): int, unsigned int, long int, unsigned long int, long long int, 或unsigned long long int.

(强调我的)

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

标准转换序列按其等级排序:精确匹配是比提升更好的转换,这是比转换更好的转换。

因此,对于表达式f(E(0))的重载决议,重载E f(int);只需要一个积分提升(from Eto int,via [conv.prom]),它具有更高等级的积分转换int f(unsigned);(from Eto unsignedvia [conv.integral])。


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

类型wchar_t(3.9.1) 或枚举类型 (7.2) 的右值可以转换为以下第一种类型的右值,这些类型可以表示其基础类型的所有值:intunsigned intlongunsigned long

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

于 2013-07-23T19:22:48.167 回答