Joã*_*nso 9 c++ namespaces friend language-lawyer
VS2015并clang编译此代码,但g++拒绝它.
namespace A {
struct B {
friend void f();
};
}
void A::f() {}
int main(){
}
Run Code Online (Sandbox Code Playgroud)
我认为g ++是正确的,因为7.3.1.2/3中的这个注释:
如果非本地类中的朋友声明首先声明了类,函数,类模板或函数模板97,则该朋友是最内部封闭命名空间的成员.友元声明本身不会使名称对非限定查找([basic.lookup.unqual])或限定查找([basic.lookup.qual])可见.[注意:如果在命名空间范围内提供匹配的声明(在类定义授予友谊之前或之后),则朋友的名称将在其命名空间中可见. - 结束注释]如果调用了友元函数或函数模板,则可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类([basic.lookup.argdep]).如果友元声明中的名称既不是限定语句也不是模板标识,并且声明是函数或详细类型说明符,则确定实体是否先前已声明的查找不应考虑最内层封闭命名空间之外的任何范围.[注意:其他形式的友元声明不能声明最内层封闭命名空间的新成员,因此遵循通常的查找规则. - 结束说明]
您引用的这部分比您强调的注释更明确:
友元声明本身不会使名称对非限定查找([basic.lookup.unqual])或限定查找([basic.lookup.qual])可见.
您的定义依赖于限定查找来查找已在命名空间内声明的函数.但是名称对于限定查找是不可见的.该代码应该被拒绝.
这是一个相关规则,见第8.3节[dcl.meaning]:
当declarator-id被限定时,声明应引用先前声明的限定符所引用的类或命名空间的成员(或者,在命名空间的情况下,引用该命名空间的内联命名空间集的元素)或专业化; 该成员不仅仅是由声明者id的嵌套名称说明符所指定的类或命名空间范围内的using声明引入的.
| 归档时间: |
|
| 查看次数: |
206 次 |
| 最近记录: |