typename
在template的聲明式中
- template< class T>//聲明方法1
- template< typename T>聲明方法2,使用typename 可以暗示參數不一定是一個class類型
使用方法1和方法2意義完全相同。但是涉及嵌套從屬名稱時隻能使用關鍵字typename:
template<typename C>
void print1st(const C& container)
{
if(container.size()>)
{
C::const_iterator iter(container.begin());//局部變量iter是從屬名稱
int value = * iter;//局部變量value是非從屬名稱
std::cout<<value;
}
}
從屬名稱(dependent name):template内出現的名稱(示例中的iter)如果相依于某個template參數(示例中的C)的名稱。如果從屬名稱在class内呈嵌套狀,則稱為嵌套從屬名稱(nested dependent name)。const_iterator也是類。
非從屬名稱(non-dependent name):不依賴于任何template參數的名稱。
嵌套從屬名稱可能導緻解析困難:
template<typename C>
void print1st(const C& container)
{
C::const_iterator* x;//如果const_iterator是類,則x是一個指向const_iterator的指針,但如果const_iterator是一個變量的名稱,則是一個相乘動作。
}
C++中一個相關的解析規則:如果解析器在template中遭遇一個嵌套從屬名稱,便假設這名稱不是一個類型,除非你通過放置關鍵字typename告訴它是
template<typename C>
void print1st(const C& container)
{
typename C::const_iterator* x;//通過放置關鍵字typename說明const_iterator是類
}
也就是說:任何時候當你想要在template中指涉一個嵌套從屬類型名稱,就必須在緊鄰它的前一個位置放置typename關鍵字作為字首詞。這個規則的例外:
- 不可以出現在base classes list内的嵌套從屬名稱之前
- 不可以出現在member initialization list(成員初值列)中作為base class修飾符
template<typename T>
class derived:public base<T>::nested{//此處不可以
public:
explivit derived(int x):base<T>::nested(x){//此處不可以
typename base<T>::nested temp;//此處可以
}
}