【问题标题】:class friend function inside a namespace命名空间内的类友元函数
【发布时间】:2012-06-11 15:36:00
【问题描述】:

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

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) 为什么我需要通过 ::f(window) 将窗口类中的成员函数 f 限定为全局?

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

【问题讨论】:

    标签: c++ namespaces friend


    【解决方案1】:

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

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

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

    【讨论】:

    • 所以 :: 访问全局命名空间的前缀是需要预先声明的函数 void f(A::window); 的前缀。它是否正确。提前致谢。
    • 是的,这在函数返回 void 时有效。但是如果它返回一个类的实例,比如 B 呢?然后编译器会拒绝“friend B ::f()”,因为它认为我们的意思是“B::f()”(即 B 类的函数,而不是全局函数)。有什么解决办法吗?
    • 我不明白你怎么能以合法的方式结束这样的名字冲突 - 你能在像 ideone 这样的东西上展示它吗?
    • 这不是冲突,而是解析错误。错误:没有在“B”类中声明的“int B::f(A::window)”成员函数davidfaure.fr/2016/friend_func.cpp
    • @DavidFaure 有点晚了,但我也遇到了同样的问题。添加括号就可以了:friend B (::f(window));。 (示例见ideone.com/x38T88
    【解决方案2】:

    应该这样做:您需要前向声明以明确 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()
    {
    }
    

    【讨论】:

      【解决方案3】:

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

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

      如果不从全局顶部作为 'friend class Na::A' 进行搜索,搜索将仅在 Na::Nb::Na 中完成。

      【讨论】:

        猜你喜欢
        • 2012-06-11
        • 1970-01-01
        • 2016-12-12
        • 1970-01-01
        • 2013-05-19
        • 2020-09-19
        • 1970-01-01
        • 1970-01-01
        • 2020-04-10
        相关资源
        最近更新 更多