在分析traits
編程以前, 咱們須要對模板參數類型tempname
和class
有必定的瞭解, 要明白他們在哪些方面不一樣, 哪些方面相同, 這樣才能對體會到traits
編程的核心. 若是你已經明白了二者, 那麼你能夠直接看下一篇了.編程
通常對模板參數類型typename
和class
認爲是同樣的. 這二者在參數類型中確實是同樣的. 你能夠寫成函數
template<class T> class point {};
也能夠寫成code
template<typename T> class point {};
這二者都是同樣的, 沒有區別. 二者typename
和class
在參數類型中沒有不一樣繼承
既然相同又爲何定義這兩個符號呢?編譯器
typename
能夠用在嵌套依賴中, 而且表示其類型, 而class
並無這樣的功能.it
什麼是嵌套依賴? 咱們以一個簡單的實例來看編譯
template<class T> class people { public: typedef T value_type; typedef T* pointer; typedef T& reference; }; template<class T> struct man { public: typedef typename T::value_type value_type; typedef typename T::pointer pointer; typedef typename T::reference reference; void print() { cout << "man" << endl; } }; int main() { man<people<int>> Man; Man.print(); exit(0); }
以上就是typename
的嵌套使用. typename
告訴編譯器這不是一個函數, 也不是一個變量而是一個類型. 這裏使用typedef又將參數類型從新定義一次, 1. 增長了一層間接性, 2. 使用的時候也不須要在寫很長的代碼.模板
這裏typename
是對people類中定義的類型進行了一次提取, 這裏將typename
改成class
就會出錯.class
typename
主要的做用:基礎
typename
可以提取出該類所定義的參數類型.並非全部的嵌套依賴類型都要加上typename
, 有一個例外 : 當繼承列表或成員初始化列表中對基類進行初始化的時候, 能夠去掉typename
關鍵字
man(int x) : T::value_type(x) {}
這裏對typename
作了一個淺顯的分析, 這也足夠咱們能夠分析traits
編程的基礎了. 我再將以上的分析作一個概括.
typename
和class
在做爲參數類型時用法同樣, 沒有區別typename
主要用於對嵌套依賴類型進行提取(萃取). 而class
沒有這樣的功能.typename
提取的一個例外是在繼承或成員初始化列表中對基類進行初始化時不用加typename
關鍵字