C++ 11访问具有合格名称的无范围枚举器

Der*_*ler 10 c++ enums language-lawyer c++11

我有一个关于C++ 11标准的措辞的问题,因为我过去没有经常深入研究它,最近发现自己对于无范围枚举的(无可争议的不重要)话题感到困惑.

我最近在代码审查中遇到了一些代码,它使用了无范围的枚举,但使用完全限定的名称访问枚举器,如下所示:

enum SomeEnum
{
  EnumA,
  ...
};

void foo()
{
  SomeEnum x = SomeEnum::EnumA;
}
Run Code Online (Sandbox Code Playgroud)

我确信这不起作用,并且SomeEnum必须是这种行为的枚举类,但是,当然,它编译得很干净.

深入研究C++ 11标准,我起初认为标准与我一致:

§7.2枚举声明:每个枚举名称和每个未作用域的枚举器都在包含枚举说明符的作用域中声明.每个作用域枚举器都在枚举范围内声明.

在我看来,这表明只有enum本身的直接包含范围才会声明未编译的枚举数.它没有提到它们也在枚举范围内声明.

但是,更进一步,标准确实包含一个示例,显示使用完全限定名称访问未作用域的枚举器.

谷歌搜索和搜索SO的一小部分给了我一些地方,声称标准现在允许完全限定名称,但没有太多的讨论.这只是示例中澄清的规范中的弱措辞,还是我还缺少其他东西?

再次,这不是惊天动地,但我希望有人可以让我直接阅读我的标准,我可以学到一些在未来情况下可能有用的东西.

Sha*_*our 7

您从C++ 11标准草案中寻找的引用来自第10段中的5.1 主要表达式部分:

表示枚举(7.2)的嵌套名称说明符,后跟该枚举的枚举数名称,是引用枚举数的qualified-id.结果是枚举器.结果的类型是枚举的类型.结果是一个prvalue.

它不限制使用范围的枚举,因此7.2 枚举声明部分中的示例:

enum direction { left='l', right='r' };

void g() {
   direction d; // OK
   d = left; // OK
   d = direction::right; // OK
}
Run Code Online (Sandbox Code Playgroud)

完全一致.这也与3.4.3 限定名称查找部分一致,该部分说明:

在将:: scope resolution运算符(5.1)应用于表示其类,名称空间或枚举的嵌套名称说明符之后,可以引用类或名称空间成员或枚举器的名称.[...]

和:

由指定枚举类型的嵌套名称说明符作为前缀的名称应表示该枚举的枚举器.

再次,没有任何限制此行为限制范围的枚举.

例子是非规范性的,但只要它们不与规范性文本冲突,那么它们应被视为一个很好的准则.