【问题标题】:Rationale behind scope resolution in strongly typed enumerations强类型枚举中范围解析背后的基本原理
【发布时间】: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中的ColorAlert的“经典”示例,有一个红色警报红色,这可能是不同的数字常数。如果没有强类型保证,可以想象,当一个人真的想要时,最终会使用警报数字常量,例如在显示器上设置红色。或者,通过整数转换和宽松的函数声明,可以想象有人最终会使用 yellow|red 之类的东西来获得橙色。

这些都不可能,那么我们到底要防御什么?

【问题讨论】:

    标签: c++ enums c++11


    【解决方案1】:

    foo(a); // 没有歧义:预期 E1,但只有 E1::a 可能

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

    您不希望表达式根据所使用的上下文改变其含义。1 + 1 始终表示相同的意思。如果您使用相同的t1 + t 总是意味着同样的事情。同样,a 无论在何处使用,都应始终表示相同的含义。

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

    【讨论】:

      猜你喜欢
      • 2019-08-29
      • 2012-04-06
      • 2018-04-24
      • 2019-06-15
      • 2022-01-07
      • 1970-01-01
      • 2012-09-16
      • 1970-01-01
      • 2012-01-19
      相关资源
      最近更新 更多