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

时间:2014-11-04 20:35:03

标签: c++ c++11 enums language-lawyer

我对C ++ 11标准的措辞有疑问,因为我过去没有经常深入研究它,并且最近发现自己对于无范围枚举的(无可争议的)主题感到困惑。

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

enum SomeEnum
{
  EnumA,
  ...
};

void foo()
{
  SomeEnum x = SomeEnum::EnumA;
}

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

窥视C ++ 11标准,我起初认为标准与我一致:

  

§7.2枚举声明:每个枚举名称和每个未编组的名称   枚举器在立即包含的范围内声明   枚举符。每个范围的枚举器都在范围内声明   枚举。

在我看来,这表明无范围的枚举数仅在enum本身的直接包含范围内声明。它没有提到它们也在枚举范围内声明。

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

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

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

1 个答案:

答案 0 :(得分:7)

您要从draft C++11 standard查找的引文来自5.1 主要表达部分,其中 10 段落中说明:

  

一个嵌套名称说明符,表示枚举(7.2),后跟   该枚举的枚举器的名称是一个限定ID   指的是普查员。结果是枚举器。的类型   结果是枚举的类型。结果是一个prvalue。

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

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

void g() {
   direction d; // OK
   d = left; // OK
   d = direction::right; // OK
}

完全一致。这也与3.4.3 合格名称查找部分一致,其中包含:

  

可以引用类或命名空间成员或枚举器的名称   在:: scope resolution operator(5.1)应用于之后   nested-name-specifier,表示其类,名称空间或   列举。 [...]

  

以名称指定的嵌套名称说明符为前缀的名称   枚举类型应代表该枚举的枚举。

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

Examples are non normative但只要他们不与规范性文本发生冲突,那么就应该将它们视为一个很好的指导原则。