程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 詳解C++的模板中typename症結字的用法

詳解C++的模板中typename症結字的用法

編輯:關於C++

詳解C++的模板中typename症結字的用法。本站提示廣大學習愛好者:(詳解C++的模板中typename症結字的用法)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++的模板中typename症結字的用法正文


typename的應用場所
用途1, 用在模板界說裡, 標明厥後的模板參數是類型參數。
例如

template<typename T, typename Y>
T foo(const T& t, const Y& y){//....};

templace<typename T>
class CTest
{
private:
 T t;
public:
 //...
}

其實,這裡最經常使用的是應用症結字class,並且兩者功效完整雷同,這裡的class和界說類時的class完整是兩回事,C++其時就是為了削減症結字,才應用了class。但終究卻不能不引入了typename,畢竟是
甚麼緣由呢?請看第二條,也就是typename的第二個用法。
用途2, 模板中標明“內嵌依附類型名”
這裡有三個詞,內嵌、依附、類型名。那末甚麼是“內嵌依附類型名(nested dependent type name)”?
請看SGI STL裡的一個例子, 只是STL中count范型算法的完成:

template <class _InputIter, class _Tp>
typename iterator_traits<_InputIter>::difference_type
count(_InputIter __first, _InputIter __last, const _Tp& __value) {
 __STL_REQUIRES(_InputIter, _InputIterator);
 __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type,
         _EqualityComparable);
 __STL_REQUIRES(_Tp, _EqualityComparable);
 typename iterator_traits<_InputIter>::difference_type __n = 0;
 for ( ; __first != __last; ++__first)
  if (*__first == __value)
   ++__n;
 return __n;
}

這裡有三個處所用到了typename:前往值、參數、變量界說。分離是:

typename iterator_traits<_InputIter>::difference_type
typename iterator_traits<_InputIter>::value_type
typename iterator_traits<_InputIter>::difference_type __n = 0;

difference_type, value_type就是依附於_InputIter(模板類型參數)的類型名。源碼以下:

template <class _Iterator>
struct iterator_traits {
 typedef typename _Iterator::iterator_category iterator_category;
 typedef typename _Iterator::value_type    value_type;
 typedef typename _Iterator::difference_type  difference_type;
 typedef typename _Iterator::pointer      pointer;
 typedef typename _Iterator::reference     reference;
};

內嵌是指界說在類名的界說中的。以上difference_type和value_type都是界說在iterator_traits中的。
依附是指依附於一個模板參數。 typename iterator_traits<_inputiter>::difference_type中difference_type依附於模板參數_InputIter。
類型名是指這裡終究要指出的是個類型名,而不是變量。例如iterator_traits<_inputiter>::difference_type完整有能夠是類iterator_traits<_inputiter> 類裡的一個static對象。並且當我們如許寫的時刻,C++默許就是說明為一個變量的。所以,為了和變量辨別,必需應用typename告知編譯器。
那末是否是一切的T::type_or_variable, 或許tmpl:type_or_variable都須要應用typename呢?不是,有以下兩個破例。
破例
(1)類模板界說中的基類列表。
例如

template<class T>
class Derived: public Base<T>::XXX
{
  ...
}

(2)類模板界說中的初始化列表。

Derived(int x) : Base<T>::xxx(x)
{
  ...
}

為何這裡不須要呢?由於編譯器曉得這裡須要的是類型照樣變量,(1)基類列內外確定是類型名,(2)初始化列內外確定是成員變量名。

typename和class的差別 
在c++ Template中許多處所都用到了typename與class這兩個症結字,並且似乎可以調換,是否是這兩個症結字完整一樣呢?
信任進修C++的人對class這個症結字都異常明確,class用於界說類,在模板引入c++後,最後界說模板的辦法為: template<class T>......
在這裡class症結字注解T是一個類型,後來為了不class在這兩個處所的應用能夠給人帶來混雜,所以引入了typename這個症結字,它的感化同
class一樣注解前面的符號為一個類型,如許在界說模板的時刻便可以應用上面的方法了:

template<typename T>......
在模板界說語法中症結字class與typename的感化完整一樣。
typename豈非僅僅在模板界說中起感化嗎?其實不是如許,typename別的一個感化為:應用嵌套依附類型(nested depended name),以下所示:

class MyArray 
{ 
  public:
  typedef int LengthType;
  .....
}

template<class T>
void MyMethod( T myarr ) 
{ 
  typedef typename T::LengthType LengthType; 
  LengthType length = myarr.GetLength; 
}

這個時刻typename的感化就是告知c++編譯器,typename前面的字符串為一個類型稱號,而不是成員函數或許成員變量,這個時刻假如後面沒有
typename,編譯器沒有任何方法曉得T::LengthType是一個類型照樣一個成員稱號(靜態數據成員或許靜態函數),所以編譯不克不及夠經由過程。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved