在强类型枚举中无条件要求显式范围解析背后的基本原理是什么?
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中的Color
和Alert
的“经典”示例,其中一个有红色警报,颜色为红色 ,也可能是不同的数字常数。如果没有强类型保证,可以想象当一个人真正想要例如警告时,最终会使用警报数字常量。在显示器上设置红色。或者,使用整数转换和松散函数声明,可以想象某人最终使用yellow|red
之类的东西来获得橙色。
这一切都不可能,那么我们究竟要反击什么呢?
答案 0 :(得分:5)
FOO的(a); //没有暧昧:E1预计,只有E1 ::一个可能的
必须知道表达式的类型。由于使用a
作为一个独立的表达方式是模棱两可的,因此a
在任何地方的使用都是模棱两可的。
你不希望表达式根据它们使用的上下文改变它们的含义。1 + 1
总是意味着同样的事情。如果您使用相同的1 + t
,t
总是意味着相同的事情。同样,a
无论在何处使用,都应始终具有相同的含义。
C ++中唯一允许根据使用它的上下文推导源类型的是统一初始化。标准明确指出“braced-init-list”不是表达式。 a
是一个表达式,因此它遵循表达式规则。