【问题标题】:Definition of friend function of a class which is inside a namespace.命名空间内的类的友元函数的定义。
【发布时间】:2011-07-28 21:52:42
【问题描述】:

我正在阅读 C++ Primer,作者说,

"如果一个类是在命名空间中定义的,那么 未申报的朋友 函数在同一个命名空间中声明:

      namespace A {
        class C {
          public:
            friend void f(const C&); // makes f a member of namespace A
        };
      }

不是说我不用在命名空间内再次声明函数 f() 了吗?

当我简单地将命名空间之外的函数 f() 定义为

void
A::f(const C& obj)
{
  std::cout << "f(const C&) " << std::endl;
}

我从 g++ 4.5 得到错误说,

FriendDeclarations1.cpp:40:23: error: ‘void A::f(const A::C&)’ should have been declared inside ‘A’

谁能告诉我作者是什么意思?

【问题讨论】:

    标签: c++ namespaces friend


    【解决方案1】:

    作者的意思是,如果没有明确声明友元函数的命名空间,那么它的命名空间是隐式声明在同一个类命名空间中的。

    所以f需要在命名空间A中定义

    #include <iostream>
    
    namespace A {
      class C {
        friend void f(const C&); // makes f a member of namespace A
        int i;
    
        public:
          C() : i(42) {}
      };
    
      void f(const A::C& obj)
      {
        std::cout << "f(const A::C&) " << std::endl;
        std::cout << "obj.i = " << obj.i << std::endl;      // access private member
      }
    }
    
    int main()
    {
      A::C ac;
    
      f(ac);
      return 0;
    }
    

    您可以通过显式声明 f 所属的命名空间来更改此行为

    #include <iostream>
    
    // forward declarations
    namespace A { class C; }
    namespace B { void f(const A::C&); }
    
    namespace A {
      class C {
        friend void B::f(const C&);
        int i;
    
      public:
        C() : i(42) {}
      };
    }
    
    namespace B {
      void f(const A::C& obj)
      {
        std::cout << "f(const A::C&) " << std::endl;
        std::cout << "obj.i = " << obj.i << std::endl;      // access private member
      }
    }
    
    int main()
    {
      A::C ac;
    
      B::f(ac);
      return 0;
    }
    

    【讨论】:

      【解决方案2】:

      标准 7.3.1.2 / 3:

      在命名空间中首先声明的每个名称都是该命名空间的成员。如果一个朋友声明在一个 非本地类首先声明一个类或函数83) 友元类或函数是最内层的成员 封闭的命名空间。 只有在该命名空间范围内提供了匹配的声明(在授予友谊的类声明之前或之后)之前,通过简单的名称查找才能找到朋友的名字。

      【讨论】:

        【解决方案3】:

        你所拥有的被解释为一个类成员定义,对于一个看起来像这样的类声明:

        class A {
          void f(const C& obj);
        }
        

        你应该这样定义 f:

        namespace A {
          void f(const C& obj)
          {
            std::cout << "f(const C&) " << std::endl;
          }
        }
        

        【讨论】:

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