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

时间:2017-11-19 23:35:29

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

关于枚举,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);
}

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

  

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

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

所以我的问题是:

  1. 立即包含枚举说明符的范围是什么? (我认为它是全局命名空间的范围)。
  2. 是否应在全局命名空间中定义枚举器AB
  3. bar函数中,为什么::A不引用枚举数,而简单引用A呢?
  4. 为什么函数::N::B中的表达式N::foo表示枚举器?
  5. 编辑1:原始声明为enum ::N::E : int {A,B};,但gcc无法对其进行解析(bug report),因此我删除了使用enum N::E : int {A,B};

    的前导冒号

    编辑2:铿锵的行为是bug

1 个答案:

答案 0 :(得分:2)

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

然后应将bar函数定义为:

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