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.