命名空间中的C++前向声明和友谊

use*_*470 6 c++ namespaces access-control friend forward-declaration

根据7.3.1.2 C++标准ISO/IEC 14882:2003(E)中的命名空间成员定义

首先在名称空间中声明的每个名称都是该名称空间的成员.如果非本地类中的友元声明首先声明一个类或函数(这意味着该类或函数的名称是不合格的),那么友元类或函数是最内层封闭命名空间的成员.

// Assume f and g have not yet been defined.
void h(int);
template <class T> void f2(T);
namespace A {
   class X {
   friend void f(X);  //  A::f(X) is a friend
      class Y {
         friend void g();  //  A::g is a friend
         friend void h(int);  //  A::h is a friend
         //  ::h not considered
         friend void f2<>(int);  //  ::f2<>(int) is a friend
      };
   };
   //  A::f, A::g and A::h are not visible here
   X x;
   void g() { f(x); }  // definition of A::g
   void f(X) { /* ... */}  // definition of A::f
   void h(int) { /* ... */ }  // definition of A::h
   //  A::f, A::g and A::h are visible here and known to be friends
}
Run Code Online (Sandbox Code Playgroud)

由于void h(int);首先在全局命名空间中声明,因此它是全局命名空间的成员.为什么friend声明friend void h(int);class Y考虑A::h,而不是::h

Vau*_*ato 2

该段末尾指出:

当查找声明为友元的类或函数的先前声明时,并且当友元类或函数的名称既不是限定名称也不是模板 ID 时,不考虑最内部封闭命名空间之外的范围。

这就是::h不考虑的原因:它既不是限定名称也不是模板 ID。这也是考虑 '::f2` 的原因,因为它是一个模板 ID。