寻找一个事先申报,由朋友介绍申报

Looking for a prior declaration, introduced by friend declaration

本文关键字:朋友 一个 寻找      更新时间:2023-10-16

有一段引用自3.4.1/7:

查找引入的类或函数的先前声明时通过友元声明,作用域在最内层封闭之外

你能举个例子来说明这个规则吗?

当然。下面的代码可以工作(两个类在同一个名称空间中):

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 :'(
    }
};

此规则规定编译器在何处查找标记为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在同一个命名空间中。因此,foo匹配Q中的友元声明。

相关文章: