强类型枚举中范围解析背后的基本原理

时间:2012-11-08 16:36:33

标签: c++ enums c++11

在强类型枚举中无条件要求显式范围解析背后的基本原理是什么?

N2347解释了旧时枚举的不同之处,即缺少隐式转换,指定存储类型的能力,以及周围范围内没有注入名称(如C ++ 03,它作为C的遗产) )。

换句话说,像在C ++ 03中编写enum E1 { a, b, c};类似于编写

const int a = 1; const int b = 2; const int c = 3;

而C ++ 11中的enum E1 class { a, b, c};更类似于

namespace E1 { const int a = 1; const int b = 2; const int c = 3; }

(不引入命名空间,并且在任何一种情况下都定义了枚举类型)。

现在,我通常不明白哪里有歧义,假设有例如下面的代码(不会编译):

enum class E1 { a, b, c };
enum class E2 { a, b, c }; // allowed now

void foo(E1 e) { ... }
void bar(E2 e) { ... }
void baz(int e) { ... }

foo(a);   // not ambigious: E1 expected, nothing but E1::a possible
bar(a);   // not ambigious: E2 expected, nothing but E2::a possible
baz(a);   // not ambigious: illegal - no name `a` in global scope

E1 x = a; // not ambigious: E1 expected, nothing but E1::a possible

我欢迎(可选)显式范围解析在某些情况下指出发生了什么,但我不明白为什么C ++ 11需要明确的范围解析,即使没有可能的方式以另一种方式解释代码。

我认为有理由期望例如void foo(E1 e);的含义更像void foo(using enum E1; E1 e);(我的语法当然是完全错误的,但你明白了。)

采用同样在N2347中的ColorAlert的“经典”示例,其中一个有红色警报颜色为红色 ,也可能是不同的数字常数。如果没有强类型保证,可以想象当一个人真正想要例如警告时,最终会使用警报数字常量。在显示器上设置红色。或者,使用整数转换和松散函数声明,可以想象某人最终使用yellow|red之类的东西来获得橙色。

这一切都不可能,那么我们究竟要反击什么呢?

1 个答案:

答案 0 :(得分:5)

  

FOO的(a); //没有暧昧:E1预计,只有E1 ::一个可能的

必须知道表达式的类型。由于使用a作为一个独立的表达方式是模棱两可的,因此a在任何地方的使用都是模棱两可的。

你不希望表达式根据它们使用的上下文改变它们的含义。1 + 1总是意味着同样的事情。如果您使用相同的1 + tt总是意味着相同的事情。同样,a无论在何处使用,都应始终具有相同的含义。

C ++中唯一允许根据使用它的上下文推导源类型的是统一初始化。标准明确指出“braced-init-list”不是表达式。 a是一个表达式,因此它遵循表达式规则。