2009-10-29 24 views
46

के लिए व्युत्पन्न वर्ग के आधार पर 'टाइपपीफ' का प्रचार करना मैं बेस क्लास को परिभाषित करने की कोशिश कर रहा हूं, जिसमें केवल टाइपपीफ है।'टेम्पलेट'

template<typename T> 
class A 
{ 
public: 
    typedef std::vector<T> Vec_t; 
}; 


template<typename T> 
class B : public A<T> 
{ 
private: 
    Vec_t v; // fails - Vec_t is not recognized 
}; 

बी में मुझे एक त्रुटि क्यों मिली है कि Vec_t पहचाना नहीं गया है और मुझे इसे स्पष्ट रूप से लिखना है?

typename A<T>::Vec_t v; 
+0

सटीक अनुलिपि यह घोषणा करने की जरूरत है: http: // stackoverflow.com/questions/1567730/inheritance-and-templates-in-c-why-are-methods-invisible –

+10

ठीक है, वास्तव में एक सटीक डुप्लिकेट नहीं है क्योंकि जिस पोस्ट में आप किसी विधि के बारे में बात करते हैं, जबकि यह एक प्रकार के बारे में बात करता है। –

+2

टाइपनाम ए :: Vec_t v; ठीक है। के लिए कोई आवश्यकता नहीं –

उत्तर

37

मुझे विश्वास है कि इस सवाल का डुप्लिकेट है, लेकिन मैं इसे अब नहीं मिल रहा।सी ++ मानक का कहना है कि आप पूरी तरह से 14.6.2/3 के अनुसार नाम अर्हता प्राप्त करना चाहिए:

एक वर्ग टेम्पलेट या एक वर्ग टेम्पलेट के एक सदस्य की परिभाषा में, यदि वर्ग टेम्पलेट की एक आधार वर्ग एक टेम्पलेट पर निर्भर करता है -परमीटर, बेस क्लास स्कोप की कक्षा के टेम्पलेट या सदस्य की परिभाषा के बिंदु पर या कक्षा टेम्पलेट या सदस्य के तत्कालता के दौरान अयोग्य नाम लुकअप के दौरान जांच नहीं की जाती है।

युपीडी: मैं अंत में डुप्लिकेट मिला: here it is

+13

वैसे, यह हमेशा मुझे बग करता है कि मुझे सब कुछ 'पुनः टाइप' करना था ... यह सुखद नहीं है, बिल्कुल सुखद नहीं है। –

+13

बीटीडब्ल्यू आपको योग्यता के दौरान सभी टेम्पलेट तर्कों और सभी की आवश्यकता नहीं है। इंजेक्शन क्लास नाम की वजह से, यह 'टाइपनाम बी :: Vec_t' लिखने के लिए पर्याप्त है –

7

क्योंकि कंपाइलर निश्चित नहीं है कि Vec_t एक प्रकार का नाम है। उदाहरण के लिए, A<T> के लिए T=intनहीं करने के लिए है कि विशेष रूप से typedef विशेष हो सकता है।

+0

'टी' प्रकार के चर के लिए, '' केवल आगे घोषित किया गया है, इसकी परिभाषा नहीं है। केवल 'ए ' जहां 't' एक प्रकार है (प्रकार परिवर्तनीय नहीं) परिभाषित किया जा सकता है (टेम्पलेट परिभाषा को विशेषज्ञता या स्पष्ट विशेषज्ञता द्वारा)। IOW, भले ही आपने सी ++ से टेम्पलेट स्पष्ट और आंशिक विशेषज्ञता हटा दी हो (और कुछ भी नहीं बदले), फिर भी यह सही नहीं होगा। – curiousguy

2

आपको Vec_t के उपयोग को स्पष्ट रूप से अर्हता प्राप्त करने की आवश्यकता है क्योंकि संकलक को पता नहीं है कि Vec_t कहां से आता है।

यह ए की संरचना के बारे में कुछ भी नहीं मान सकता है, क्योंकि कक्षा टेम्पलेट ए विशेष हो सकता है। विशेषज्ञता में Vec_t शामिल हो सकता है जो टाइपिफ़ नहीं है, या इसमें सदस्य Vec_t भी शामिल नहीं हो सकता है।

1

Vec_t एक आश्रित नाम नहीं है, और संकलक को पता है कि यह किसी भी टेम्पलेट्स (इस मामले में आधार वर्ग) instantiating बिना है की जरूरत है। ,

template <class T> 
class X 
{ 
    std::string s; 
} 

यहाँ के रूप में अच्छी संकलक std :: स्ट्रिंग के बारे में पता करने के लिए भले ही एक्स instantiated नहीं है की जरूरत है के बाद से नाम टेम्पलेट तर्क टी पर जहाँ तक निर्भर नहीं करता है (: यह वास्तव में से अलग नहीं है संकलक मान सकते हैं)।

कुल मिलाकर, एक टेम्पलेट आधार वर्ग में typedefs बल्कि व्युत्पन्न वर्ग में उपयोग के लिए बेकार लग रहे हैं। हालांकि, टाइपिफ उपयोगकर्ता के लिए उपयोगी हैं।

+0

क्या आपका मतलब है 'कक्षा एक्स: टी {'यहां? – curiousguy

26

टेम्पलेट्स के मामले में निर्भर और परमाणु नामों पर कुछ नाम है।

नाम और दूसरों टेम्पलेट पैरामीटर टी पर निर्भर करता है, तो इसकी निर्भर नाम उन पैरामीटर टी पर निर्भर नहीं है स्वतंत्र नाम हैं।

यहाँ नियम है: संकलक निर्भर आधार वर्ग में नज़र नहीं करता है (जैसे ए) जब nondependent नाम को देख (Vec_t की तरह)। नतीजतन, संकलक को पता नहीं है कि वे मौजूद हैं अकेले ही प्रकार हैं।

संकलक कल्पना नहीं कर सकते कि Vec_t एक प्रकार जब तक यह T जानता है, क्योंकि A<T> का एक संभावित विशेषज्ञता जहां A<T>:: Vec_t एक एक डेटा सदस्य

तो समाधान typename

typename A<T>::Vec_t v; ← good 
का उपयोग है है नहीं है

मुझे सलाह है कि आप इस https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types पर जाएं।

पुरानी (टूट) लिंक: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18

+0

आपका एकमात्र उत्तर था जो एक स्पष्टीकरण के अलावा समाधान प्रदान करना प्रतीत होता था। धन्यवाद। – Richard

+1

लिंक टूटा हुआ है –

+0

यदि आप मुझे सूचित करते हैं कि आपने लिंक को सही किया है तो मैं आपको +1 देता हूं। –

0

यह अवधारणा इस बात से जुड़ी हो सकती है कि हम std::vector<T> का उपयोग कैसे करते हैं। उदाहरण के लिए, यदि हमारे पास std::vector<int> Foo है। अब, हम इसके किसी भी सदस्य प्रकार का उपयोग करने का निर्णय लेते हैं, iterator कहें। इस परिदृश्य में हम स्पष्ट रूप से

std::vector<int>::iterator foo_iterator; 
अपने मामले में

इसी तरह का उल्लेख है, आदेश template <typename T> class A की Vec_t एक सार्वजनिक सदस्य प्रकार का उपयोग करने में, आप स्पष्ट रूप से के रूप में

A<T>::Vec_t v; 
OR 
A<int>::Vec_t int_type; 
संबंधित मुद्दे