2013-01-01 19 views
7

मेरे समझ नहीं था कि एक friend घोषणा भी एक आगे घोषणा के रूप में एक वर्ग के लिए है, तो class विनिर्देशक इस्तेमाल किया गया था कि इस उदाहरण में के रूप में काम कर सकता है,:दोस्त घोषणा आगे की घोषणा

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

class B {}; 

int main() {} 

हालांकि, जी ++ (4.6। 3 और 4.7.0) मुझे निम्न त्रुटि (छ ++ देता है - 4.7 extended friend declarations के लिए समर्थन करना चाहिए था), जो एक आगे घोषणा के बिना की उम्मीद है: मेरी उम्मीदों की पुष्टि करने के

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

की कोशिश में है कि friend class B; को आगे की घोषणा के रूप में कार्य करना चाहिए, मुझे this answer और this answer मिला, लेकिन न तो निर्णायक था (या मैं कम से कम उनसे अधिक निष्कर्ष निकाला नहीं था) इसलिए मैंने सी ++ 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

@ के-बॉलो तो जब यह कहता है कि एक नई कक्षा घोषित करती है, तो क्या यह पूरी तरह से मित्र घोषणा के प्रयोजनों के लिए है, लेकिन किसी और चीज के लाभ के लिए नहीं? – JaredC

+0

@ जेरेडसी: यह मेरे बारे में सही लगता है ... –

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 
} 
संबंधित मुद्दे