c++ - 在 C++14 中,在哪个范围内声明了重新声明的枚举的无范围枚举数?

标签 c++ enums c++14 language-lawyer

C++14(准确地说,N4296)在 7.2:11 中提到了枚举:

Each enum-name and each unscoped enumerator is declared in the scope that immediately contains the enum-specifier.

现在,如果命名空间 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说:

no member named 'A' in the global namespace; did you mean simply 'A'?

Gcc 无法编译 bar() 中的两行。所以 gcc 和 clang 都在命名空间 N.

中声明枚举

所以我的问题是:

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

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

编辑 2:clang 的行为是 bug

最佳答案

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

然后应该将 bar 函数定义为:

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

关于c++ - 在 C++14 中,在哪个范围内声明了重新声明的枚举的无范围枚举数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47383199/

相关文章:

c++ - 使用VS2010作为IDE,使用MSVC 2005作为编译器

Java Enum 值代表 java.lang 类

C++ double 到二进制表示(重新解释转换)

c++ - 在 visual studio 中使用 __LINE__ 宏作为模板参数

C++:创建正确类型的回调函数

c++ - 仅适用于 C++14 的变量模板

c++ - 在 C++ 中,我可以使用来自不同文件的值安全地初始化 unordered_map 吗?

java - 枚举和开关帮助。 Java学习者

java - Java 将枚举编译成什么?

c++ - make_unique : Why is f(new T) exception safe 的异常安全