2013-04-04 11 views
11

निम्न कोड मुझे संकलन त्रुटि 'मान' इस दायरे में घोषित नहीं किया गया थाबेस क्लास टेम्पलेट का सदस्य व्युत्पन्न क्लास टेम्पलेट में स्कोप से बाहर है, उसी टेम्पलेट तर्क

template<class T> 
struct Base { 
    int value; 
}; 

template <class T> 
struct Derived : public Base<T> { 
    int getValue() { return value; } 
}; 

मैं यह बहुत अजीब

  • Base<std::string> से Derived इनहेरिट करती है, कोड को संकलित करता है,
  • अगर मैं return Base<T>::value, कोड को संकलित करता है कि लगता है।

कोड संकलित क्यों नहीं है? Derived<T>::getValue() के दायरे में 'मूल्य' घोषित नहीं किया गया है?

उत्तर

16

क्योंकि value एक अयोग्य नाम है, और नाम देखने के पहले चरण के दौरान, संकलक कोई सुराग नहीं यह एक डेटा सदस्य एक आधार वर्ग से विरासत में मिली है (यह अभी तक Base<T> instantiated नहीं किया गया है) है कि होगा। इस प्रकार, यह वैश्विक नामस्थान खोजेगा, और value नामक कोई चर नहीं मिलेगा; नतीजतन, यह एक त्रुटि उत्सर्जित करेगा।

यहाँ इस समस्या को हल करने के लिए एक विशिष्ट दृष्टिकोण है:

template <class T> 
struct Derived : public Base<T> { 
    int getValue() { return this->value; } 
    //      ^^^^^^ 
}; 

explictly अपसंदर्भन this संकलक कि नाम इस प्रकार है कि डेटा सदस्य (संभवत: विरासत में मिला है) का नाम है बताता है, और देखने में देरी हो जाना चाहिए उस बिंदु पर जहां सदस्य कार्य वास्तव में तत्काल है। बेशक, कर के अपने समाधान:

return Base<T>::value; 

, उतना ही अच्छा है, क्योंकि यह भी संकलक कि value आधार वर्ग Base<T> से विरासत में मिली है बताता है।

के लिए क्या Base<std::string> से पाने चिंताओं, संकलक तुरंत जाने के लिए और ऊपर है कि क्या Base<std::string>value नामित (क्योंकि यह किसी भी टेम्पलेट पैरामीटर पर निर्भर नहीं करता) एक डेटा सदस्य शामिल हैं देख सकते हैं और यदि यह मामला है, यह करने के लिए सक्षम हो जाएगा निर्धारित करें कि अभिव्यक्ति अच्छी तरह से बनाई गई है।

हालांकि, अगर आपके आधार वर्ग Base<T>, जहां T नाम देखने के पहले चरण के दौरान अज्ञात है है, संकलक नहीं बता सकता कि value है (विभिन्न T रों लिए Base की विशेषज्ञता भी value बिल्कुल नहीं हो सकता है) ।

अनुच्छेद 14.6/C++ 11 स्टैंडर्ड की 3:

कक्षा या वर्ग टेम्पलेट की परिभाषा में, यदि एक आधार वर्ग एक टेम्पलेट पैरामीटर पर निर्भर करता है, आधार वर्ग गुंजाइश नहीं है वर्ग टेम्पलेट या सदस्य या कक्षा टेम्पलेट या सदस्य के तत्काल के दौरान, अयोग्य नाम लुकअप के दौरान जांच की गई। [...] [उदाहरण:

struct A { 
    struct B {/.../}; 
    int a; 
    int Y; 
}; 

int a; 

    template<class T> struct Y : T { 
    struct B {/.../}; 
    B b; // The B defined in Y 
    void f(int i) { a = i; } // ::a 
    Y* p; // Y<T> 
    }; 

Y<A> ya; 

सदस्यों A::B, A::a, और टेम्पलेट तर्क A की A::Y Y<A> में नामों के बंधन को प्रभावित नहीं करते। - अंतिम उदाहरण]

+0

उत्कृष्ट उत्तर। – Oswald

+0

@ ओस्वाल्ड: धन्यवाद, खुशी है कि मैं –

+0

उत्कृष्ट मदद कर सकता हूं, जैसा कि मैं हमेशा जोड़ सकता हूं :)। –

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