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

§7.1.6.3/1 (C++14) doesn't accept the construction in the second snippet below. Why is this?

第一部分

我正在详细研究 opaque-enum-declarations 和 elaborated-type-specifiers 已经几天了,我真的很想有人证实这一点。 GCC 和 VS2013 不编译这段代码(clang 编译)我相信 clang 符合 §7.1.6.3/1,因为 enum E 是一个 elaborated-type-specifier 这不是声明的唯一组成部分 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';
}

第二部分:

下面的代码段与上面的代码段非常相似,但无法编译。我明白为什么它没有(详细类型说明符 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';
}

N4140 [basic.scope.hiding]/2:

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.

int E 的声明似乎在 int 的声明点之后在全局范围内隐藏了枚举 E 的名称。但是,名称 E::bqualified-idnested-name-specifier of E::,因此规则适用于合格名称查找。特别是 [basic.lookup.qual]/1:

The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator (5.1) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a :: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that :: considers only namespaces, types, and templates whose specializations are types. [emphasis added.] If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.

所以 clang 是合规的,GCC 和 MSVC 不是。