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

Bel*_*loc 5 c++ enums language-lawyer c++14

第一部分:

我已经研究了一些细节opaque-enum-declaration s和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';
}
Run Code Online (Sandbox Code Playgroud)

第二部分:

下面的代码段与上面的代码段非常类似,不会编译.我理解为什么它没有(详细说明类型说明符 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';
}
Run Code Online (Sandbox Code Playgroud)

Cas*_*sey 7

N4140 [basic.scope.hiding]/2:

类名(9.1)或枚举名(7.2)可以通过在同一范围内声明的变量,数据成员,函数或枚举器的名称隐藏.如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,函数或枚举器名称可见.

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

在将::范围解析运算符(5.1)应用于表示其类,命名空间或枚举的嵌套名称说明符之后,可以引用类或命名空间成员或枚举数的名称.如果嵌套名称说明:: 符中的作用域解析运算符前面没有decltype-specifier,则查找之前的名称仅考虑其专门化为类型的名称空间,类型和模板.[ 重点补充说.如果找到的名称未指定命名空间或类,枚举或依赖类型,则程序格式错误.::

因此,铿锵声是顺从的,GCC和MSVC都没有.