2011-12-12 86 views
4

我想在模板類中定義一個類型名稱,我可以在其他地方使用它來引用類中成員的類型。在模板中使用typedef和typename

template <class T> 
class CA 
{ 
public: 
    //typedef typename T::iterator iterator_type; 
    typedef typename T ElementType1; // compile error on this line 
    //typedef T ElementType2; 

    T m_element; 
}; 

,並使用它像這樣:

template <class T> 
class CDerived : public CBase<typename T::ElementType1> 
{ 
//... 
}; 

,並宣佈對象,如:

typedef CDerived<CA> MyNewClass; 

這是不可能的?我有一些代碼,編譯正確下VS2010而不是下使用該行的Xcode:

typedef typename T ElementType1; 

顯然編譯器期待類型名稱後,一個合格的名字,但我不明白如何可以有一個模板類型。

我不明白在這種情況下ElementType1和ElementType2之間的區別。

我看了很多關於堆棧溢出的問題,但大多數似乎只涉及像我的例子中的iterator_type這樣的聲明。

回答

4

編譯器已經知道T是一個類型(class T),因此在第一種情況下不需要typename限定符。 OTOH,編譯器事先並不知道T::ElementType1是一種類型;這取決於T最終成爲什麼。

+0

確定很酷,回答我的問題,我需要使用'typedef T ElementType'。真的,我不確定typename是否應該在那裏。我明白它在'CBase '中的用法。這是關於類型名稱[鏈接](http://pages.cs.wisc.edu/~driscoll/typename.html)的更多信息。似乎VS2010接受ElementType1聲明,但是,也許不是gcc。 – Robotbugs

4

typename只能用於限定合格的名稱;它並不適用 緊隨其後的名字,但對合格的名字, 即:

typedef typename T::X x; 

typename適用於X,而不是T。由於這個原因,它在合格的名稱之前只是合法的(在這個使用中) 。非限定名稱 必須位於編譯器可以知道該名稱是否爲 類型的上下文中。 (實際上,這只是 從屬基類中定義的類型中的一個問題,並且這些可以被限定。)