【发布时间】:2012-11-08 16:36:33
【问题描述】:
在强类型枚举中无条件要求显式范围解析的基本原理是什么?
N2347 解释了与老式枚举的区别,后者没有隐式转换、指定存储类型的能力以及在周围范围内没有注入名称(如在 C++03 中,它具有 C 的传统) )。
换句话说,在 C++03 中写enum E1 { a, b, c}; 类似于写
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); 是合理的(我的语法当然完全错误,但你明白了)。
以同样在N2347中的Color和Alert的“经典”示例,有一个红色警报和红色,这可能是不同的数字常数。如果没有强类型保证,可以想象,当一个人真的想要时,最终会使用警报数字常量,例如在显示器上设置红色。或者,通过整数转换和宽松的函数声明,可以想象有人最终会使用 yellow|red 之类的东西来获得橙色。
这些都不可能,那么我们到底要防御什么?
【问题讨论】: