在C++ 14中,范围是声明重新声明的枚举的未作用域的枚举器?

Jan*_*šil 21 c++ enums language-lawyer c++14

关于枚举,C++ 14(正是N4296)在7.2:11中说:

每个枚举名称和每个未作用域的枚举器都在包含枚举说明符的作用域中声明.

现在如果命名空间N包含枚举E的opaque-enum声明会发生什么,稍后枚举是从全局命名空间完全声明的?我们应该在全局命名空间或命名空间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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

Gcc无法在bar()中编译这两行.所以gcc和clang都声明了名称空间中的枚举N.

所以我的问题是:

  1. 立即包含枚举说明符的范围是什么?(我认为它是全局命名空间的范围).
  2. 如果统计员A,B在全局命名空间中定义?
  3. bar函数中,为什么::A不引用枚举器,但简单A呢?
  4. 为什么::N::B函数中的表达式N::foo表示枚举器?

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

编辑2:铿锵的行为是一个错误

小智 2

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

bar 函数应定义为:

int bar() {
    return int(N::A);
    //SAME AS --> return int(::N::A);
}
Run Code Online (Sandbox Code Playgroud)