2014-10-25 9 views
5

मैं समझने की कोशिश कर रहा हूं कि हम कक्षा-सदस्य-पहुंच अभिव्यक्ति के माध्यम से नेस्टेड प्रकार का उपयोग क्यों नहीं कर सकते हैं।हम कक्षा-सदस्य-पहुंच अभिव्यक्ति के माध्यम से नेस्टेड प्रकार का उपयोग क्यों नहीं कर सकते?

struct U 
{ 
    struct A 
    { 
     static int v; 
     int a; 
    }; 

    struct B 
    { 
     int b; 
    }; 
}; 

U a; 

typedef a.A T; //'a' does not name a type 

int main() 
{ 
    std::cout << typeid(a.A).hash_code(); //invalid use of 'struct U::A' 
    struct a.A b;       //trying to declare a variable of type U::A 
              //error: expected unqualified-id before '.' token 
    a.A b;        //the same as above 
              //error: expected unqualified-id before '.' token 
    a.A.v = 5;       //error: expected unqualified-id before '.' token 
} 

DEMO

स्टैंडर्ड का कहना है:: उदाहरण के लिए, हम निम्नलिखित वर्ग है

धारा N3797::5.2.5/2 [expr.ref]

For the first option (dot) the first expression shall have complete class type. For the second option (arrow) the first expression shall have pointer to complete class type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot).In either case, the id-expression shall name a member of the class or of one of its base classes.

जबकि, खंड N3797::9.2/1 [class.mem] वर्ग के एक परिभाषा देता है सदस्य:

Members of a class are data members, member functions (9.3), nested types, and enumerators.

तो मुझे नेस्टेड प्रकार के उपयोग के लिए प्रतिबंध नहीं दिख रहा है। क्यों नहीं?

उत्तर

4

आगे बढ़ें [expr।रेफरी]

(4.4) If E2 is a nested type, the expression E1.E2 is ill-formed.

+0

यह एक खंड है "* यदि ई 2 को टाइप करने के लिए घोषित किया गया है" टी के संदर्भ में, "*", मुझे नहीं लगता कि यह यहां लागू होता है। – luk32

+0

@ luk32 "यदि ई 2 को" टी के संदर्भ "के रूप में घोषित किया गया है, तो E1.E2 एक अंतराल है; E1.E2 का प्रकार टी है। ** अन्यथा, निम्न नियमों में से एक लागू होता है। **" – user657267

+0

ओह मैं इसे उलट गया। मैंने इसे 3 बार पढ़ा था कि यह टी का संदर्भ होना था। हालांकि मैं जवाब में अधिक संदर्भ डालूंगा। मुझे लगता है कि एक पूरा नियम होना महत्वपूर्ण है। आईएमओ यह है। – luk32

2

मानक एक ऑब्जेक्ट के प्रकार के बारे में बात कर रहा है जो एक चर का प्रतिनिधित्व करता है।
आपको कक्षा के दायरे तक पहुंचने की आवश्यकता है, चर नहीं।

struct U 
{ 
    struct A 
    { 
     static int v; 
     int a; 
    } VarNameForA; 

    struct B 
    { 
     int b; 
    }; 
    B VarNameOfB; 
}; 

प्रकार का उपयोग करने की गुंजाइश ऑपरेटर :: का उपयोग करें:

और U से नेस्टेड वर्ग के सदस्यों तक पहुँचने के लिए, आप 2 तरीकों से ऐसा करने के लिए कर रहे हैं, उस प्रकार का कोई सदस्य बनाने की जरूरत ।

यहाँ कैसे आप सब कुछ आप की कोशिश की करते हैं:

U a; 

typedef decltype(a) varType; 
typedef varType::A nestedType; 

int main() 
{ 
    std::cout << typeid(U::A).hash_code(); 
    struct U::A b;       
    U u; 
    u.VarNameForA.a = 5; 
    u.VarNameOfB.b = 6; 

    U::A::c = 3;       

} 

सदस्यों को आप ऑपरेटर dot (.) का उपयोग, प्रकार और स्टैटिक्स आप scope :: ऑपरेटर उपयोग करने की आवश्यकता के लिए के लिए।

+0

मुझे लगता है कि ओपी को पता है ::, लेकिन यह इंगित करता है कि N3797 :: 5.2.5/2 अन्यथा कहता है। –

+0

ईमानदारी से, मुझे नहीं लगता कि यह सवाल का जवाब देता है। प्रश्न यह नहीं है कि कोड कैसे काम करें और सभी प्रकारों को सही तरीके से परिभाषित करें। लेकिन आप '.' के माध्यम से टाइप क्यों नहीं कर सकते हैं, जबकि दिए गए उद्धरण सुझाव देते हैं कि आपको सक्षम होना चाहिए। नेस्टेड प्रकार को सदस्य के रूप में सूचीबद्ध किया गया है, इसलिए आपका उत्तर भी सुझाव देता है कि 'ठीक' होना चाहिए। – luk32

2

आप a.A को एक प्रकार के विनिर्देशक के रूप में उपयोग करने का प्रयास करते हैं।

वर्ग के सदस्य पहुँच नियम (5.2.5) का उल्लेख केवल भाव के लिए मान्य हैं करने के लिए प्रकार विनिर्देशक और typenames के लिए नहीं (5/1: "कोई व्यंजक ऑपरेटरों और ऑपरेंड के एक दृश्य है कि एक गणना निर्दिष्ट करता है एक अभिव्यक्ति के परिणामस्वरूप एक मूल्य हो सकता है और साइड इफेक्ट्स का कारण बन सकता है। ")।

आपको मानक के अनुभाग 7.1.6 में टाइप विनिर्देश के नियमों को देखना होगा। वहां ऑपरेटर . का कोई उपयोग नहीं है। विस्तृत प्रकार (7.1.6.3) एक टाइपनाम पर घटकों को गठबंधन करने के लिए :: का उपयोग करें।

बजना त्रुटि संदेश आप अपने संकलक से प्राप्त की तुलना में अधिक स्पष्ट है: "एक प्रकार पर डॉट ऑपरेटर का उपयोग नहीं कर सकते हैं")।

वैसे, आपके U नेस्टेड प्रकारों की परिभाषा के साथ एक खाली संरचना (कोई डेटा नहीं) है। यही कारण है कि a.A.v = 5; भी एक त्रुटि है: यहां कोई अंतराल नहीं है जिसे असाइन किया जा सकता है।

+0

तो क्या 'decltype (ए.ए.) 'काम करना चाहिए? मैं यह भी बता सकता हूं कि यह कहां कहा जाता है कि 5.2.5 केवल अभिव्यक्तियों पर लागू होता है? – luk32

+0

उत्कृष्ट सवाल! STD 7.1.6.2 अस्वीकरण (अभिव्यक्ति) को एक प्रकार विनिर्देशक परिभाषित करता है। लेकिन अभिव्यक्ति मूल्यों पर हैं, न कि प्रकारों पर और एए किसी मान को इंगित नहीं करता है (* 7.1.6.2.4: यदि ऐसी कोई इकाई नहीं है, (...) प्रोग्राम खराब है *) – Christophe

+0

क्लैंग से त्रुटि संदेश घोषणा के लिए (एए) पिछले लोगों से अलग है। यह कहता है "'यू' में 'यू' में टाइप सदस्य 'ए' को संदर्भित नहीं किया जा सकता है, जो सुझाव देता है कि संकलक इस मामले में उपयोगकर्ता 657267 द्वारा वर्णित नियम लागू होता है। – Christophe

संबंधित मुद्दे

 संबंधित मुद्दे