typename和typedef關鍵字

typename指示一個類型名,而非定義一個類型,以下聲明瞭一個Seq::iterator類型的變量itr,其中Seq是一個模板實例化時才知道的類:

    typename Seq::iterator itr;

如果沒有typename指示,Seq::iterator會被認爲是Seq的靜態變量,而不是類型名。

typename關鍵字不會定義一個類型,如果你想定義一個新類型的話,你必須這樣:

    typedef typename Seq::iterator ITR;

1、類型說明typedef

類型說明的格式爲:
     typedef 類型 定義名;
    類型說明只定義了一個數據類型的新名字而不是定義一種新的數據類型。定義名錶示這個類型的新名字。
    例如: 用下面語句定義整型數的新名字:
     typedef int SIGNED_INT;
    使用說明後, SIGNED_INT就成爲int的同義詞了, 此時可以用SIGNED_INT 定
義整型變量。
    例如: SIGNED_INT i, j;(與int i, j等效)。
    但 long SIGNED_INT i, j; 是非法的。
    typedef同樣可用來說明結構、聯合以及枚舉和類。
    說明一個結構的格式爲:
      typedef struct{
          數據類型 成員名;
          數據類型 成員名;
          ...
        } 結構名;
    此時可直接用結構名定義結構變量了。例如:
     typedef struct{
          char name[8];
          int class;
          char subclass[6];
          float math, phys, chem, engl, biol;
      } student;
      student Liuqi;
    則Liuqi被定義爲結構數組和結構指針。
2、類型解釋Typename

Typename關鍵字告訴了編譯器把一個特殊的名字解釋成一個類型,在下列情況下必須對一個name使用typename關鍵字:

1. 一個唯一的name(可以作爲類型理解),它嵌套在另一個類型中的。

2. 依賴於一個模板參數,就是說:模板參數在某種程度上包含這個name。當模板參數使編譯器在指認一個類型時產生了誤解。

 

保險期間,你應該在所有編譯器可能錯把一個type當成一個變量的地方使用typename。就像上面那個例子中的T::id,因爲我們使用了typename,所以編譯器就知道了它是一個類型,可以用來聲明並創建實例。

 

給你一個簡明的使用指南:如果你的類型在模板參數中是有限制的,那你就必須使用typename.

 

#include <iostream>
#include <typeinfo> // for typeid() operator

using namespace std;

template <typename TP>
struct COne {   // default member is public
    typedef TP one_value_type;
};

template <typename COne>   // 用一個模板類作爲模板參數, 這是很常見的
struct CTwo {
    // 請注意以下兩行
    // typedef COne:one_value_type two_value_type;   // *1
    typedef typename COne:one_value_type two_value_type; // *2
};

// 以上兩個模板類只是定義了兩個內部的public類型, 但請注意第二個類CTwo的two_value_type類型
// 依賴COne的one_value_type, 而後者又取決於COne模板類實例化時傳入的參數類型.

int main()
{
    typedef COne<int> OneInt_type;
    typedef CTwo< OneInt_type > TwoInt_type;
    TwoInt_type::two_value_type i;
    int j;
    if ( typeid(i) == typeid(j) )   // 如果i是int型變量
        cout << "Right!" << endl;   // 打印Right
    return;
}
以上例子在Linux下用G++ 2.93編譯通過, 結果打印"Right". 但是如果把*1行的註釋號去掉, 註釋
*2行, 則編譯時報錯, 編譯器不知道COne:one_value_type爲何物. 通常在模板類參數中的類型到
實例化之後纔會顯露真身, 但這個CTwo類偏偏又要依賴一個已經存在的COne模板類, 希望能夠預先
保證CTwo::two_value_type與COne:one_value屬於同一類型, 這是就只好請typename出山, 告訴
編譯器, 後面的COne:one_value_type是一個已經存在於某處的類型的名字(type name), 這樣編譯
器就可以順利的工作了.

發佈了49 篇原創文章 · 獲贊 4 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章