在C++14中,在哪个作用域中声明了重新声明枚举的非范围枚举器



C++14(确切地说,N4296)在7.2:11:中谈到枚举

每个枚举名称和每个未受范围限制的枚举器都在范围中声明它立即包含枚举说明符。

现在,如果名称空间N包含枚举E的不透明枚举声明,然后枚举从全局名称空间完全声明,会发生什么?我们应该在全局名称空间中还是在名称空间N中找到它的枚举器?

当然,为了不透明地声明一个无范围的枚举,它应该有一个固定的底层类型。请考虑以下代码。

namespace N { enum E : int; }
enum N::E : int {A,B};
namespace N {
int foo() {
return int(::N::B);
}
}
int bar() {
//return int(::A);
return int(A);
}

bar中的第一行被注释掉,因为clang++ -std=c++14说:

全局命名空间中没有名为"A"的成员;你的意思只是"A"吗?

Gcc无法编译bar()中的两行。因此,gcc和clang都在名称空间N中声明枚举。

所以我的问题是:

  1. 立即包含枚举说明符的作用域是什么?(我认为这是全局命名空间的范围)
  2. 枚举器AB是否应该在全局命名空间中定义
  3. bar函数中,为什么::A不引用枚举器,而简单的A引用呢
  4. 为什么函数N::foo中的表达式::N::B表示枚举器

EDIT 1:原始声明是enum ::N::E : int {A,B};,但gcc无法解析它(错误报告),所以我删除了前导冒号以使用enum N::E : int {A,B};

编辑2:叮当的行为是一个错误

枚举E是在命名空间N中声明的,即使其定义是在全局命名空间中设置的。因此,它只能在N.的范围内访问

条函数应定义为:

int bar() {
return int(N::A);
//SAME AS --> return int(::N::A);
}

最新更新