第一部分:
我已经研究了一些细节 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';
}
答案 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不是。