簡體   English   中英

命名空間中的C ++前向聲明和友誼

[英]C++ Forward Declaration and Friendship in Namespace

根據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
}

由於void h(int); 首先在全局命名空間中聲明它,它是全局命名空間的成員。 為什么朋友聲明friend void h(int); class Y考慮A::h而不是::h

在該段末尾,它指出:

當查找聲明為朋友的類或函數的先前聲明時,並且當友元類或函數的名稱既不是限定名稱也不是模板ID時,不考慮最內部封閉命名空間之外的范圍。

這就是為什么不考慮::h :它既不是限定名也不是模板ID。 這也是考慮':: f2`的原因,因為它是模板ID。

我認為內部聲明會影響全局命名空間中的聲明。 此外,友元聲明本身是前向聲明,因此它們會影響全局命名空間中的聲明,而不僅僅是“引用”這些函數。

參考N3485中的3.3.10.1“名稱隱藏”:

名稱可以通過嵌套聲明性區域或派生類(10.2)中相同名稱的顯式聲明來隱藏。

11.3.4朋友:

首先在朋友聲明中聲明的函數具有外部鏈接(3.5)。 否則,該功能保留其先前的鏈接(7.1.1)。

看3.5.2:

當名稱具有外部鏈接時,其表示的實體可以通過其他翻譯單元的范圍或同一翻譯單元的其他范圍中的名稱來引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM