寻找事先声明,由朋友声明介绍

时间:2014-05-28 08:28:38

标签: c++ namespaces friend

引用自3.4.1 / 7:

  

在寻找引入的类或函数的事先声明时   由朋友声明,范围在最里面的封闭   不考虑名称空间范围;

您能举例说明这条规则吗?

2 个答案:

答案 0 :(得分:1)

此规则规定编译器查找标记为friend的函数或类的位置。它规定,编译器只检查与允许friend访问的类相同的命名空间中的函数或类。它不会检查其他名称空间或外部名称空间中的函数或类。


此代码将产生错误:

#include <iostream>

namespace a {
  class Q { int x; friend void foo(Q q); };
}

// function foo is in outer namespace (not in a)
void foo(a::Q q) { std::cout << q.x << std::endl; }
//                              ^^^ ERROR q.x is private

int main() {
    a::Q q;
    foo(q);
}

原因是函数foo不在名称空间a中,而是在外部名称空间中(在本例中是全局名称空间)。因此fooQ中的朋友声明不匹配。


此代码可以使用:

#include <iostream>

namespace a {
  class Q { int x; friend void foo(Q q); };
}

// function foo is in same namespace as Q
namespace a {
  void foo(Q q) { std::cout << q.x << std::endl; }
//                            ^^^ OK access allowed by friend
}

int main() {
    a::Q q;
    a::foo(q);
}

这是有效的,因为函数foo现在与Q位于同一名称空间中。因此,fooQ中的朋友声明匹配。

答案 1 :(得分:1)

不确定。此代码有效(两个类都在同一名称空间中):

namespace Foo {
  class Bar
  {
  friend class FooBar;
  public:
    Bar() : i(0){}
  private:
    int i;
  };

  class FooBar
  {
    FooBar( Bar & other )
    {
      other.i = 1;
    }
  };
}//namespace Foo

此代码失败(友元类在Foo的封闭命名空间之外,因此查找失败并且您看到int Foo::i is private within this context错误:

namespace Foo {
  class Bar
  {
  friend class FooBar;
  public:
    Bar() : i(0){}
  private:
    int i;
  };
}//namespace Foo

class FooBar
{
    FooBar( Foo::Bar & other )
    {
        other.i = 1;//Oops :'(
    }
};