2012-11-08 39 views
2

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

N2347解释了与旧式枚举不同的地方,这些旧式枚举不存在隐式转换,指定存储类型的能力以及在周围范围内不注入名称(如在C++ 03中,它具有作为C)。

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

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

enum E1 class { a, b, c};如在C++ 11被更类似于像

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);(我的语法当然是完全错误的,但你明白了)。

以的ColorAlert,这也是在N2347“经典”的例子,一个具有红色警报,并且红色,其可以是不同的数值常量,太。如果没有强类型保证,可以想象当人们真的想要例如使用警告数字常量时,结果是最终的。在显示器上设置红色。或者,使用整数转换和宽松的函数声明,可以想象有人最终会使用类似yellow|red的东西来获取橙色。

这一切都不可能,所以我们究竟是在防范什么呢?

回答

5

foo(a); //不含糊:E1预期,只有E1 ::可能

必须知道表达式的类型。而且由于使用a作为独立表达是不明确的,因此在任何地方使用a都是不明确的。

您不希望表达式根据其使用的上下文来更改它们的含义。1 + 1始终表示相同的事物。如果你使用相同的t1 + t总是意味着相同的东西。同样,无论在何处使用,a应该始终表示相同的内容。

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

+0

这很有道理,谢谢。 – Damon