1. //在C++中typename一般用來聲明模板的模板參數(template parameter): template<typename T> class X; //T是一個模板參數 2. /*但是還有一個關鍵的用法。首先是兩個概念: 1). qualified name 例如:std::cout, std::endl;這樣含有作用域符號(::)的就是限定名, 當我們用using聲明將cout,endl引入到當前作用域之后就可以直接使用 這兩個名稱,這個時候cout,endl就不是限定名了。 2). dependent name dependent name是依賴於模板參數的類型,例如:*/ template <typename T> class X { int i; std::vector<int> ivec; std::vector<int>::iterator iter; T type; std::vector<T> tvec; std::vector<T>::iterator titer; }; /* 前3個成員變量是不依賴於模板參數,所以是non-dependent name,后3個是dependent name ,直到實例化該模板的時候才會知道到底是什么類型。*/ //下面來討論typename的第二種用法。現在假設我們有一個類如下: template <typename T> class Y { T::iterator *iter; ... }; /* 我們可能本意是想定義一個迭代器對象,例如我們如果用vector<int>來實例化這個模板,那么iter 則應該是一個迭代器指針,但是,如果我們用下面這個類來實例化這個模板:*/ class cType { static int iterator; ... }; /* 那么T::iterator *iter會被編譯器解釋為兩個數相乘。事實上,C++編譯器會采用第二種解釋方法 ,即使iterator的確是一個類型名。 為了避免這種矛盾,當我們適用qualified dependent name的時候,需要用typename來指出這是一個 類型名.即: */ template <typename T> class Y { typename T::iterator *iter; typedef typename T::iterator iterator; //定義了Y::iterator類型名稱 ... }; //typename 指出下面緊跟着的名稱是一個類型
總結:T::iterator這種名稱,由於iterator具體是類型還是成員變量取決於T的類型實現,所以當我們
知道T::iterator是個類型名稱時,如果我們要使用這個類型名,前面必須要加typename.
