§7.1.6.3/ 1(C ++ 14)不接受下面第二个片段中的构造。为什么是这样?

时间:2015-03-20 21:35:41

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

第一部分

我已经研究了一些细节 opaque-enum-declaration elaborated-type-specifier 已经有好几天了,我真的希望有人来确认一下。 GCC和VS2013不编译此代码(clang确实),我相信clang符合§7.1.6.3/ 1,因为enum E详细类型说明符,不是宣言的唯一组成部分enum E e = E::b;。我的分析是否正确?

#include <iostream>
enum class E : char {a = 'a', b};
int E;
enum E e = E::b;        // Doesn't compile in GCC and VS2013
int main()
{
    std::cout << (char)(e) << '\n';
}

第二部分:

下面的代码段与上面的代码段非常类似,不能编译。我理解为什么它没有( elaborated-type-specifier enum E是声明enum E;的唯一组成部分,而§7.1.6.3/ 1不允许这样做)。我想知道的是为什么编译器不能接受这种结构?

#include <iostream>
enum class E : char {a = 'a', b};
int E;
enum E;                 // This doesn't compile.
E e = E::b;        
int main()
{
    std::cout << (char)(e) << '\n';
}

1 个答案:

答案 0 :(得分:7)

N4140 [basic.scope.hiding] / 2:

  

类名(9.1)或枚举名(7.2)可以通过变量名称,数据成员隐藏,   在同一范围内声明的函数或枚举器。如果是类或枚举名称和变量,则为数据   成员,函数或枚举器在同一范围内(以任何顺序)声明具有相同的名称,即   在变量,数据成员,函数或枚举器名称所在的位置隐藏类或枚举名称   可见。

int E的声明点之后,E的声明似乎隐藏了全局范围内的枚举int的名称。但是,名称E::b qualified-id ,其中嵌套名称说明符E::,因此适用于限定名称查找的规则。特别是,[basic.lookup.qual] / 1:

  

可以在::范围解析后引用类或命名空间成员或枚举数的名称   operator(5.1)应用于表示其类,名称空间或枚举的嵌套名称说明符。如果是::   嵌套名称说明符中的作用域解析运算符前面没有 decltype-specifier 查找   ::之前的名称仅考虑其专业化类型的名称空间,类型和模板。 [强调添加。]   如果找到的名称未指定命名空间或类,枚举或依赖类型,则为程序   是不正确的。

所以clang是顺从的,GCC和MSVC不是。