以下(LiveWorkspace here)被GCC 4.7.2,GCC 4.8.0和ICC 13.0.1拒绝。
namespace A {
namespace B {
void C();
}
using B::C;
}
class D {
friend void A::C();
};
此外,它崩溃了Clang 3.2(!)。我已经为崩溃错误提交了一个错误报告和patch,但我不能100%确定这段代码是否真的出错,因为我在§7.3中找不到任何内容。 3 [namespace.udecl] 或§11.3[class.friend] 明确解决了这种情况,但也许在我的各种名称说明符之一的定义中有一些东西错过。
此外,似乎所有四个编译器都接受以下(LiveWorkspace here):
namespace A {
namespace B {
class C;
}
using B::C;
}
class D {
friend class A::C;
};
这两种情况似乎没有任何根本的不同,所以我很好奇GCC和ICC拒绝第一个例子的理由,但不是这个例子,如果有的话。任何更熟悉标准的人都可以找到解决这个问题的任何内容吗?
这绝对是一个小问题,但是因为我正在修补它,我想确定我做的是正确的事情......
编辑:This is patched now in clang/trunk!
NEW EDIT :Johannes的回答解释了为什么我的原始示例被拒绝,但它似乎无法解释为什么GCC和ICC也拒绝以下(LiveWorkspace here):
namespace A {
namespace B {
void C();
}
using B::C;
class D {
friend void C();
};
}
答案 0 :(得分:4)
8.3p1:
当declarator-id合格时, 声明应引用先前声明的限定符所在的类或命名空间的成员 引用(或者,在命名空间的情况下,引用该命名空间的内联命名空间集合的元素(7.3.1)) 或专业化; 该成员不仅仅是通过使用声明引入的 在由declarator-id的nested-name-specifier指定的类或命名空间的范围内。
class foo;
或class foo::bar;
不包含声明者ID,因此不受此规则的影响。相反,foo::bar
是详细类型说明符(7.1.6.3)的一部分。