STL知識準備: 1. C++關鍵字typename (轉)

gugu99發表於2008-03-02
STL知識準備: 1. C++關鍵字typename (轉)[@more@]

/*******************************************************************************
 *  SGI*STL是STL之父Alexander Stepanov和STL巨匠Matt Austern等人的作品, 是當今  *
 *  最富盛名、最出色的STL實現版本,全部和說明文件可從  *
 *  載, 是我們學習STL的最佳範本. 但是眾所周知, STL使用了大量複雜艱深的C++特性, *
 *  加上STL本身的複雜和龐大, 使得閱讀程式碼本身就成為一件非常困難的工作. 以下文  *
 *  字是我在學習STL過程中得到的一些和猜測, 希望能對大家有所幫助, 更希望能  *
 *  得到大家的批評和指正, 以利於我們的共同提高.  *
 *  myan  *
 *******************************************************************************/

在SGI*STL原始碼裡, typename這個新的C++關鍵字得使用可以說是隨處可見. 很多以前學習過
C++的人可能還不認識typename, 其實它的常規用法很簡單: 在宣告模板或者模板類時,
傳統的寫法:
template
generic_function() {
//........
}

亦可以寫成
template
  ------------
generic_func() {
//...............
}
引入這個關鍵字主要是為了避免class可能給人帶來的混淆.
本來typename的用法就是這麼簡單, 但是STL原始碼中還有typename的一種不常見的用法, 如果
不瞭解, 閱讀原始碼時就會遇到困難. 因為目前我找不到有關這個問題的說明, 所以自己試驗了
一下, 得到一個猜測, 現簡介如下, 請有識之士斧正.

首先看一段SGI*STL原始碼, 摘自stl_iterator.h

1: template
2: inline insert_iterator<_container> inserter(_Container& __x, _Iterator __i)
3: {
4:  typedef typename _Container::iterator __iter;
5:  return insert_iterator<_container>(__x, __iter(__i));
6:  }

令人費解的部分在第四行. 請大家在看我的解釋之前先想一想, 我不敢保證下面解釋的正確性和
全面性.

解釋:
  我認為typename的語義是: 通知, 在typename後面被宣告的東西是一個型別, 而不是別的
什麼東西.

例子:
// tpname.cpp
#include
#include   // for typeid() operator

using namespace std;

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

template   // 用一個模板類作為模板引數, 這是很常見的
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 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;
}
//  ~tpname.cpp

以上例子在下用G++ 2.91編譯透過, 結果列印"Right". 但是如果把*1行的註釋號去掉, 註釋
*2行, 則編譯時報錯, 編譯器不知道COne::one_value_type為何物. 通常在模板類引數中的型別到
例項化之後才會顯露真身, 但這個CTwo類偏偏又要依賴一個已經存在的COne模板類, 希望能夠預先
保證CTwo::two_value_type與COne::one_value屬於同一型別, 這是就只好請typename出山, 告訴
編譯器, 後面的COne::one_value_type是一個已經存在於某處的型別的名字(type name), 這樣編譯
器就可以順利的工作了.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1000269/,如需轉載,請註明出處,否則將追究法律責任。

相關文章