模板中tempname與class區別

前言

在分析traits編程以前, 咱們須要對模板參數類型tempnameclass有必定的瞭解, 要明白他們在哪些方面不一樣, 哪些方面相同, 這樣才能對體會到traits編程的核心. 若是你已經明白了二者, 那麼你能夠直接看下一篇了.編程

相同之處

通常對模板參數類型typenameclass認爲是同樣的. 這二者在參數類型中確實是同樣的. 你能夠寫成函數

template<class T> 
class point {};

也能夠寫成code

template<typename T>
class point {};

這二者都是同樣的, 沒有區別. 二者typenameclass參數類型中沒有不一樣繼承

既然相同又爲何定義這兩個符號呢?編譯器

  1. 最開始定義定義模板的方法就是template<class T> , 可是class畢竟都認爲是一個類, 在使用時不免會有些點混淆, 也就定義了typename來標誌參數類型
  2. 最重要關於 typename可使用嵌套依賴類型, 也就是類型能夠嵌套使用. 這也是兩個的不一樣之處.

不一樣之處

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編程的基礎了. 我再將以上的分析作一個概括.

  1. typenameclass在做爲參數類型時用法同樣, 沒有區別
  2. typename主要用於對嵌套依賴類型進行提取(萃取). 而class沒有這樣的功能.
  3. typename提取的一個例外是在繼承或成員初始化列表中對基類進行初始化時不用加typename關鍵字
相關文章
相關標籤/搜索