2012-06-30 164 views
32

考慮下面的頭文件:C++模板類型名稱迭代器

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

首先,正如其他的答案已經指出,類型名稱嵌套依賴類型需要與預先考慮typename關鍵字。

,當模板是完全專用的,這意味着list<tnode<int>*>::iterator不需要typename,但在外部類仍取決於模板參數Ttypename必須存在不需要關鍵字。

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(); 

聲明將宣佈一個函數,而不是一個迭代器。刪除()。上述這裏提供

A Description of the C++ typename keyword

的答案

1

更多底色我曾在一個不同但類似的問題,我想的typedef子節點的迭代器與:

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

這給了我相同的編譯器錯誤。有了這裏的建議和上述鏈接的幫助,我的問題的解決方案是使用

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

代替。