我试图在命名空间之外定义一个类友元函数,如下所示:
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)
。所以我的问题是:void f(A::window rhs)
成为类A::window的友元。编辑:(阅读答案后)
为什么我需要通过执行
::f(window)
来将窗口类中的成员函数 f 限定为全局函数?
为什么在这种特殊情况下我需要预先声明函数 f(A::window) ,而当类不是在命名空间内定义时,在函数被声明为友元之后声明该函数是可以的。
除了添加
::
之外,您还需要转发声明它,例如:
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;
}
请注意,要使此前向声明起作用,您还需要前向声明该类!
这应该可以做到:您需要前向声明来明确 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()
{
}
使用 ::,您还可以与外部包装命名空间中的类成为好友:
namespace Na {
class A;
namespace Nb {
class B {
...
friend class ::Na::A;
};
如果不从全局顶部作为“友元类 Na::A”,搜索将仅在 Na::Nb::Na 中完成。