2013-12-20 49 views
0

我有一個情況我想隱藏一個基類和限制,可以從它繼承的類:交通不便當朋友結構繼承類

namespace _detail { 
    class Private abstract final { 
     struct Base abstract { 
     protected: 
      Base() {} 
     }; 

     friend struct ::A; 
     friend struct ::B; 
     friend struct ::C; 
    }; 
} 

struct A : _detail::Private::Base {}; //error 
struct B : _detail::Private::Base {}; //error 
struct C : _detail::Private::Base {}; //error 

編譯器告訴我,_detail::Private::Base是無法進入ABC,即使他們是Private的朋友。我之前使用過這種模式沒有問題,但與其他時間相比,我無法真正看到有什麼不同。我沒有看到什麼?

+0

'abstract final'? –

+0

'friend struct A;'在名稱空間'_detail'中聲明一個結構爲朋友。 – dyp

+0

@sftrabbit它的工作原理,爲什麼不呢? – NmdMystery

回答

3

C++語言不允許你使用合格的名字(例如::A)在朋友的聲明,除非這些合格的名稱是指先前聲明的實體。實際上,這個規則在任何地方都是虛擬的,不僅在朋友聲明中:合格的名字必須引用先前聲明的實體。

在您的情況下,您在朋友聲明friend struct ::A中使用了限定名稱::A。爲此,編譯器必須事先知道來自全局名稱空間的struct A。在你的情況下A沒有宣佈在這一點上,這使得friend struct ::A聲明格式不正確。它甚至不應該按照語言的正式規則進行編譯。

如果你的編譯器接受這個,你必須諮詢你的編譯器documentatuion來找出它的含義。我懷疑friend struct ::A對於未知::A被解釋爲等同於friend struct A,即它聲明_detail::A作爲朋友。

如果您在聲明名稱空間_detail前進行了前向聲明struct A;,它可能會使其按預期工作。