内联命名空间和歧义声明

3
我想知道是否允许这样做:
namespace A {
  inline namespace B {
    int a;
  }
  int a;
}

void foo() {
  A::a = 0; // clang 3.4 compiles, but gcc doesn't
}

标准规定:

最后,在通过显式限定符(3.4.3.2)在封闭命名空间中查找名称时,即使在封闭命名空间中存在该名称的声明,也将包括使用指令带入的内联命名空间的成员。

但是我不理解。


1
既不是gcc 4.9也不是clang 3.5允许此代码,您可以在wandbox上尝试...但clang 3.4可以,看起来像是一个错误。 - Shafik Yaghmour
@ShafikYaghmour 谢谢你,Shafik。这是一个很棒的资源。是的,我在我的工作中尝试了这段代码,在这里我有clang-3.4。 - Bikineev
1个回答

5

看起来这是一个 pre clang 3.5 bug,有两个缺陷报告 812861。861 中的解决方案并将以下内容添加到 3.4.3.2 [namespace.qual]接下来的强调是我的):

对于名称空间 X 和名称 m,名称空间限定查找集 S(X,m) 定义如下:令 S'(X,m) 为 X 和其内联名称空间集合(7.3.1 [namespace.def])中所有 m 的声明集。如果 S'(X,m) 不为空,则 S(X,m) 等于 S'(X,m);否则,S(X,m) 等于 X 的 using 指令所指定的所有非内联名称空间 Ni 的 S(Ni,m) 的并集,以及它的内联名称空间集。

还有相关的补充:

如果 S(X,m) 是空集,程序将不符合规范。否则,如果 S(X,m) 仅有一个成员,或者引用的上下文是 using-declaration (7.3.3 [namespace.udecl]),那么 S(X,m) 就是 m 所需的声明集合。否则,如果使用 m 的方式不允许从 S(X,m) 中选择唯一的声明,程序将不符合规范。这段文字似乎是在 C++11 之前添加的,在 N3337 中可以找到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接