13

我试图在命名空间之外定义一个类朋友函数,如下所示:

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::window 类的朋友。

编辑:(阅读答案后)

2)为什么我需要通过 do 将窗口类中的成员函数 f 限定为全局::f(window)

3)为什么我需要在这种特殊情况下预先声明函数 f(A::window) ,而当类不是在命名空间内定义时,在函数被声明为友元之后声明函数是可以的。

4

3 回答 3

24

除了添加::你需要转发声明它,例如:

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;
}

请注意,要使此前向声明起作用,您也需要前向声明该类!

于 2012-06-07T15:00:29.423 回答
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()
{
}
于 2012-06-07T15:03:47.113 回答
0

使用 ::,您还可以为外部包装命名空间中的类加好友:

namespace Na {
class A;
namespace Nb {
class B {
...
   friend class ::Na::A;
};

无需从全局顶部作为“朋友类 Na::A”,搜索将仅在 Na::Nb::Na 中完成。

于 2021-05-21T02:40:37.993 回答