我试图在命名空间之外定义一个类朋友函数,如下所示:
namespace A{
class window{
private:
int a;
friend void f(window);
};
}
void f(A::window rhs){
cout << rhs.a << endl;
}
我得到一个错误说有歧义。并且有两个候选人void A::f(A::window);
和void f(A::window)
。所以我的问题是:
1)如何使全局函数void f(A::window rhs)
成为A ::窗口的朋友。
编辑:(阅读答案后)
2)为什么我需要通过::f(window)
将窗口类中的成员函数f限定为全局?
3)为什么我需要在这种特殊情况下预先声明函数f(A :: window),而当类不在命名空间内定义时,在声明函数之后声明函数是okey朋友。
答案 0 :(得分:19)
除了添加::
之外,还需要转发声明它,例如:
namespace A { class window; }
void f(A::window);
namespace A{
class window{
private:
int a;
friend void ::f(window);
};
}
void f(A::window rhs){
std::cout << rhs.a << std::endl;
}
请注意,要使此前向声明起作用,您还需要转发声明该类!
答案 1 :(得分:5)
这应该这样做:你需要转发声明以使其清楚f是在全局命名空间中(而不是文件静态):
#include <string>
#include <iostream>
using namespace std;
////// forward declare magic:
namespace A{ class window; }
void f(A::window rhs);
//////
namespace A {
class window {
private:
int a;
friend void ::f(window);
};
}
void f(A::window rhs) {
cout << rhs.a << endl;
}
int main()
{
}
答案 2 :(得分:0)
使用 ::,您还可以将外部包装命名空间中的类添加为友元:
namespace Na {
class A;
namespace Nb {
class B {
...
friend class ::Na::A;
};
不从全局顶部作为'friend class Na::A',搜索将只在Na::Nb::Na中进行。