在强类型枚举中无条件地要求明确范围解析的基本原理是什么?
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 需要显式范围解析,即使没有可能的方式以另一种方式解释代码。
在我看来,期望 examplevoid foo(E1 e);
的含义更像是void foo(using enum E1; E1 e);
(我的语法当然完全错误,但你明白了)是合理的。
以N2347中的Color
and的“经典”示例为例,其中一个具有red alert和red,它们也可能是不同的数字常量。如果没有强类型保证,可以想象当一个人真的想在显示器上设置红色时,最终会使用警报数字常量。或者,通过整数转换和宽松的函数声明,可以想象有人最终会使用类似获取橙色的东西。Alert
yellow|red
这些都不可能,那么我们到底要防御什么?