2013-01-01 111 views
7

我的理解是一個friend宣言還可以作爲一個向前聲明爲一類,如果使用了class符,如下例所示:朋友申報不能向前聲明

class A 
{ 
    friend class B; 
    B* b; 
}; 

class B {}; 

int main() {} 

然而,G ++(4.6。 3和4.7.0)給了我下面的錯誤(G ++ - 4.7應該有extended friend declarations支持),這是沒有預先聲明預計:

main.cpp:6:2: error: ‘B’ does not name a type

在試圖確認我的期望是,friend class B;應該作爲前向聲明,我發現this answerthis answer,但都不是結論性的(或者我至少不能從他們得出多少結論),所以我試圖去諮詢C++ 11標準並發現這個例子:

class X2 { 
    friend Ct; // OK: class C is a friend 
    friend D; // error: no type-name D in scope 
    friend class D; // OK: elaborated-type-specifier declares new class 
} 

根據我對第三個聲明的閱讀,我的friend class B應該是一個闡述類型說明符,聲明一個新類

我剛剛開始瞭解官方標準的措辭,所以我必須錯過一些東西。我誤解了什麼?

回答

5

您的friend class B;聲明確實作爲前向聲明,但是直到提供匹配聲明才能通過名稱查找找到此類聲明。

[class.friend]/11

If a friend declaration appears in a local class (9.8) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope. For a friend function declaration, if there is no prior declaration, the program is ill-formed. For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing nonclass scope.

+0

不,這真的是':: B':HTTP ://ideone.com/bEgZrq。請注意「內部封閉*非類*範圍」。 – aschepler

+0

@ K-ballo所以當它說宣佈一個新的類時,這僅僅是爲了朋友聲明的目的,而不是爲了其他任何好處? – JaredC

+0

@JaredC:這聽起來對我來說很合適...... –

6

看看11.3第11段:

For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing nonclass scope.

Example:

class X; 
void a(); 
void f() { 
    class Y; 
    extern void b(); 
    class A { 
    friend class X; // OK, but X is a local class, not ::X 
    friend class Y; // OK 
    friend class Z; // OK, introduces local class Z. 
    friend void a(); // error, ::a is not considered 
    friend void b(); // OK 
    friend void c(); // error 
    }; 
    X *px;   // OK, but ::X is found 
    Z *pz;   // error, no Z is found 
}