C++;命名空间中的转发声明和友谊 >在C++标准ISO/IEC 1488~2003(E)中7.3.1.2命名空间成员定义

C++;命名空间中的转发声明和友谊 >在C++标准ISO/IEC 1488~2003(E)中7.3.1.2命名空间成员定义,c++,namespaces,friend,access-control,forward-declaration,C++,Namespaces,Friend,Access Control,Forward Declaration,名称空间中首先声明的每个名称都是该名称空间的成员 命名空间。如果非本地类中的友元声明首先声明 类或函数(这意味着类或函数的名称 函数不合格)友元类或函数是 最里面的封闭命名空间 //假设f和g尚未定义。 空h(int); 模板空隙f2(T); 名称空间A{ X类{ 朋友void f(X);//A::f(X)是朋友 Y类{ 朋友void g();//A::g是朋友 friend void h(int);//A::h是朋友 //::h未考虑 朋友空f2(int);/::f2(int)是朋友 }; }

名称空间中首先声明的每个名称都是该名称空间的成员 命名空间。如果非本地类中的友元声明首先声明 类或函数(这意味着类或函数的名称 函数不合格)友元类或函数是 最里面的封闭命名空间

//假设f和g尚未定义。
空h(int);
模板空隙f2(T);
名称空间A{
X类{
朋友void f(X);//A::f(X)是朋友
Y类{
朋友void g();//A::g是朋友
friend void h(int);//A::h是朋友
//::h未考虑
朋友空f2(int);/::f2(int)是朋友
};
};
//A::f、A::g和A::h在此处不可见
X;
void g(){f(x);}//A::g的定义
void f(X){/*…*/}//A::f的定义
void h(int){/*…*/}//A::h的定义
//A::f、A::g和A::h在这里可见,并且被认为是朋友
}

因为
void h(int)
首先在全局命名空间中声明,它是全局命名空间的成员。为什么朋友声明
朋友无效h(int) <代码>类y>代码>考虑<代码>::h < />代码>而不是<代码>::h < /代码> 

< p>我认为内部声明在全局命名空间中隐藏了这些声明。而且,友元声明本身是前向声明,因此它们隐藏了全局命名空间中的声明,而不仅仅是“引用”这些函数

参考N3485中的3.3.10.1“名称隐藏”:

一个名称可以通过一个相同名称的显式声明隐藏在 嵌套的声明性区域或派生类(10.2)

11.3.4朋友:

首先在友元声明中声明的函数具有外部链接 (3.5). 否则,该功能将保留其先前的链接(7.1.1)

查看3.5.2:

当名称具有外部链接时,它所表示的实体可以是 从其他翻译单位的范围或从 同一翻译单位的其他范围


该段末尾指出:

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


这就是为什么不考虑
::h
:它既不是限定名,也不是模板id。这也是为什么考虑“::f2”,因为它是模板id。

您只是在类X上声明了一个无效的朋友。如果它做了任何其他事情,我会担心。前面声明的void h(int)在全局中,但Y显然在命名空间A中。
// 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
}