涉及老式枚举和整数类型的重载解析

Pie*_*yts 7 c++ enums overload-resolution implicit-conversion

考虑以下代码

#include <iostream>

using namespace std;

enum myEnum { a, b, c };

void test(myEnum e) {
  cout << "myEnum overload" << endl;
}

void test(unsigned int i) {
  cout << "unsigned int overload" << endl;
}

int main() {
  test(a);
  test(1);
  test(1u);  

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

(我知道enum classenum这种事情更安全,但是我使用的是带有旧式枚举的开源代码。)

当我用g ++ 4.4.7编译并运行它时,我得到了

myEnum overload
unsigned int overload
unsigned int overload
Run Code Online (Sandbox Code Playgroud)

也就是说,编译器更喜欢转换int,而unsigned int不是将其转换为myEnum。这就是我想要的,但是我想知道是否总是可以保证。该标准并未明确规定底层类型myEnum应该是什么,因此我认为也许是这样int,也许会更受欢迎unsigned int

但是当我注释掉unsigned int超载时,出现此错误:

enum_overload.cpp: In function ‘int main()’:
enum_overload.cpp:17: error: invalid conversion from ‘int’ to ‘myEnum’
enum_overload.cpp:17: error:   initializing argument 1 of ‘void test(myEnum)’
enum_overload.cpp:18: error: invalid conversion from ‘unsigned int’ to ‘myEnum’
enum_overload.cpp:18: error:   initializing argument 1 of ‘void test(myEnum)’
Run Code Online (Sandbox Code Playgroud)

这是否意味着旧式枚举隐式转换它们的基础类型,但不能那些类型?如果真是这样,那将回答我的上一个问题:如果整数类型不能转换为myEnum,则保证过载解析的行为如上所述。

L. *_* F. 4

[转化积分]/1 :

无作用域枚举类型的纯右值可以转换为整数类型的纯右值。

反之则不然。没有从整数类型到无作用域枚举类型的隐式转换:

看来您将此与将整数值转换为枚举类型相混淆:[expr.static.cast]/10

整型或枚举类型的值可以显式转换为完全枚举类型。如果原始值在枚举值([dcl.enum])范围内,则该值保持不变。否则,行为是未定义的。浮点类型的值也可以显式转换为枚举类型。结果值与将原始值转换为枚举的基础类型 ([conv.fpint]),然后转换为枚举类型相同。

(强调我的)

但这只能通过显式强制转换来完成:

E x1 = static_cast<E>(1) // yes
E x2 = E(1);             // yes
E x3 = 1;                // no
E x4(1);                 // no
Run Code Online (Sandbox Code Playgroud)