2012-06-30 24 views
32

निम्नलिखित हेडर फाइल पर विचार करें:सी ++ टेम्पलेट typename इटरेटर

template <typename T> struct tNode 
{ 
    T Data;      //the data contained within this node 
    list<tNode<T>*> SubNodes;  //a list of tNodes pointers under this tNode 

    tNode(const T& theData) 
    //PRE: theData is initialized 
    //POST: this->data == theData and this->SubNodes have an initial capacity 
    //  equal to INIT_CAPACITY, it is set to the head of SubNodes 
    { 
     this->Data = theData; 
     SubNodes(INIT_CAPACITY); //INIT_CAPACITY is 10 
    } 

}; 

अब किसी अन्य फ़ाइल से कोड की एक पंक्ति पर विचार करें:

list<tNode<T>*>::iterator it(); //iterate through the SubNodes 

संकलक मुझे यह त्रुटि संदेश दे रहा है: Tree.h:38:17: error: need ‘typename’ before ‘std::list<tNode<T>*>::iterator’ because ‘std::list<tNode<T>*>’ is a dependent scope

मुझे नहीं पता कि संकलक इस पर चिल्ला रहा है कि क्यों।

उत्तर

54

list<tNode<T>*>::iterator में, आप एक निर्भर नाम है, वह है, एक ऐसा नाम है जो टेम्पलेट पैरामीटर पर निर्भर करता है।

इस प्रकार, कंपाइलर list<tNode<T>*> का निरीक्षण नहीं कर सकता (इसकी इस परिभाषा में इसकी परिभाषा नहीं है) और इसलिए यह नहीं पता कि list<tNode<T>*>::iterator या तो एक स्थिर क्षेत्र या एक प्रकार है।

ऐसी स्थिति में, संकलक मानता है कि यह एक क्षेत्र है, इसलिए आपके मामले में यह एक वाक्यविन्यास त्रुटि उत्पन्न करता है। इस मुद्दे को हल करने के लिए, सिर्फ संकलक है कि यह घोषणा की typename आगे रख कर एक प्रकार है बता:

typename list<tNode<T>*>::iterator it 
5

list<tNode<T>*>::iterator एक आश्रित नाम है, एक प्रकार जो टेम्पलेट पैरामीटर पर निर्भर करता है। आदेश है कि चर घोषित करने के लिए है, तो आप typename कीवर्ड का उपयोग करने की आवश्यकता है:

typename list<tNode<T>*>::iterator it = ...; 
16

सबसे पहले, अन्य उत्तर पहले से ही बताया गया है, प्रकार के नाम निर्भर प्रकार में नेस्ट साथ prepended करने की आवश्यकता है typename कीवर्ड।

कीवर्ड की जरूरत नहीं है कि जब टेम्पलेट पूरी तरह से विशेष है, जिसका अर्थ है कि list<tnode<int>*>::iteratortypename की जरूरत नहीं है, लेकिन जब बाहरी वर्ग अभी भी टेम्पलेट पैरामीटर T पर निर्भर करता है, typename मौजूद होना चाहिए।

template <typename T> void foo() { 
    list<tnode<int>*>::iterator it1; // OK without typename 
    typename list<tnode<T>*>::iterator it2; // typename necessary 
} 

दूसरे, यहां तक ​​कि typename साथ

typename list<tNode<T>*>::iterator it(); 

घोषणा एक समारोह, नहीं पुनरावर्तक घोषित करेंगे। () हटाएं।

typedef std::vector<NodeType*>::iterator ChildIterator; 

: जवाब पर

1

अधिक backround ऊपर यहाँ

A Description of the C++ typename keyword

प्रदान की जाती है मैं मैं के साथ बच्चे नोड्स के लिए पुनरावर्तक typedef करना चाहता था कि में एक अलग लेकिन इसी तरह की समस्या थी जिसने मुझे एक ही संकलक त्रुटि दी। यहां दिए गए सुझावों और उपरोक्त लिंक की सहायता के साथ, मेरी समस्या का समाधान

typedef typename std::vector<NodeType*>::iterator ChildIterator; 

का उपयोग करना है।