以下代码分为两个源文件。
首先:
namespace A {
// two friends; neither is declared apart from a friend declaration
// these functions implicitly are members of namespace A
class C {
friend void f2(); // won’t be found, unless otherwise declared
friend void f1(const C&); // found by argument-dependent lookup
};
}
int main()
{
A::C obj;
f1(obj); // ok: find A::f through the friend declaration in A::C
A::f2(); // no member named f2 in namespace A
}
和第二个:
#include <iostream>
namespace A {
class C;
void f1(const C&) {
std::cout << 1;
}
void f2() {
std::cout << 2;
}
}
第一段代码是从C ++入门复制而来的,唯一的区别是C ++引物调用 f2()没有前缀命名空间。第二部分是我的补充。我现在想知道 f1 和 f2 隐含地是命名空间A的成员,为什么 A :: f2()仍然是错误的 ADL可以找到f1(obj)吗?
答案 0 :(得分:3)
这是7.3.1.2中的规则,导致A::f2()
失败:
如果非本地类中的友元声明首先声明了类,函数,类模板或函数模板,则该友元是最内层封闭命名空间的成员。友元声明本身不会使名称对非限定查找(3.4.1)或限定查找(3.4.3)可见。
答案 1 :(得分:0)
在第一个代码块中,f2
位于A::C
的词法范围内,即该名称在A::C
范围内可见。它在A::C
之外不可见。
要使f2
超出A::C
的范围,您需要在A
中声明或定义它。