天天看點

Effective C++第七章-模闆和泛型程式設計之typename與嵌套從屬名稱

typename

在template的聲明式中

  1. template< class T>//聲明方法1
  2. 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關鍵字作為字首詞。這個規則的例外:

  1. 不可以出現在base classes list内的嵌套從屬名稱之前
  2. 不可以出現在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;//此處可以
    }
}
           

繼續閱讀