欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來(lái)到入門教程網(wǎng)!

C語(yǔ)言

當(dāng)前位置:主頁(yè) > 軟件編程 > C語(yǔ)言 >

C++的template模板中class與typename關(guān)鍵字的區(qū)別分析

來(lái)源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C語(yǔ)言|點(diǎn)擊: 次

在C++模板中,可以使用class或者typename來(lái)聲明模板參數(shù),那么這兩個(gè)關(guān)鍵字有什么區(qū)別呢?

模板參數(shù)聲明
對(duì)于模板參數(shù)聲明,這兩個(gè)參數(shù)沒(méi)有區(qū)別,含義是一樣的。

template class Simple;
template class Simple;

上面兩行都是聲明一個(gè)模板類Simple.

表明類型
假如我們有這樣一段代碼:

template


void add(const T &acontainer, T &sum)
{
  T::const_iterator iter = container.begin();
  for (; iter != container.end(); ++iter) {
    sum += *iter;
  }
}

iter的類型是T::const_iterator,這個(gè)類型依賴模板參數(shù)T。把依賴模板參數(shù)的名稱稱為依賴名稱。當(dāng)這個(gè)依賴名稱又在一個(gè)類中時(shí),稱為嵌套依賴名稱。相對(duì)的,稱為非嵌套依賴名稱。

嵌套依賴名稱會(huì)導(dǎo)致編譯器編譯的困難,例如下面的代碼:

template


void add(const T &container)
{
  T::const_iterator *x;
  ...
}

這看起來(lái)像聲明一個(gè)變量x,它的類型為T::const_iterator *。但是編譯器并不知道,也有可能類T中又一個(gè)static數(shù)據(jù)成員const_iterator,或者正好有一個(gè)全局變量x。這時(shí)上面的代碼就變成乘法操作。這是因?yàn)?C++編譯器在處理模板的時(shí)候,會(huì)將需要推導(dǎo)的數(shù)據(jù)類型暫時(shí)擱置,到運(yùn)行時(shí)再確定。

當(dāng)編譯器遇到一個(gè)模板中的嵌套依賴名稱時(shí),編譯器將它作為變量對(duì)待。因此,需要顯示的告訴編譯器,這就需要使用關(guān)鍵字typename。

template
void add(const T &container, T &sum)
{
  typename T::const_iterator iter = container.begin();
  for (; iter != container.end(); ++iter) {
    sum += *iter;
  }
}

因此,使用嵌套依賴的類型名稱時(shí),都需要使用typename指定它是一種類型。

例外
嵌套依賴名稱在基類列表中,或者在成員初始化列表中時(shí),不能使用typename。

template
class Drived: public Base::Nested { // 基類列表,不要使用typename
public:
  explicit Derived(int x): Base::Nested(x) { // 成員初始化列表,不要使用typename
    typename Base::Nested temp;
    ...
  }
  ...
};

另外一些注意點(diǎn)

1、嵌套從屬名稱(nested dependent names)
假如template內(nèi)出現(xiàn)的名稱如果依賴于某個(gè)模板參數(shù),則稱其為從屬名稱(dependent names),如果從屬名稱在class內(nèi)呈嵌套狀則稱之為嵌套從屬名稱(nested dependent names)。
例如:

templaet <typename T>void myPrint(const T& t){
  t::const_iterator iter(t.begin());
}

假設(shè)模板參數(shù)列表中的參數(shù)表示一個(gè)容器類型,則我們知道t::const_iterator一個(gè)依賴模板參數(shù)并且在容器內(nèi)部,所以t::const_iterator是一個(gè)嵌套從屬名稱。

在我們知道t是什么之前沒(méi)有辦法可以知道t::const_iterator是否是一個(gè)類型,因?yàn)橛羞€可能是個(gè)靜態(tài)(static)成員變量,考慮下面的例子:

template <typename T>void myPrint(const T& t){
  t::const_iterator * x;
}

如果const_iterator是t的靜態(tài)成員變量,則上面的t::const_iterator * x;中的*表示乘法,如果是個(gè)類型則表示聲明一個(gè)指向t::const_iterator類型的指針。
從而給編譯器造成困惑(因?yàn)槲覀儾恢纓是什么)。

C++有個(gè)規(guī)定:當(dāng)解析器在模板中遇到一個(gè)嵌套從屬名稱時(shí)便假定這個(gè)名稱不是類型,除非你用關(guān)鍵字typename指定它是:

template <typename T>void myPrint(const T& t){
  typename t::const_iterator * x;   //這樣便不會(huì)造成困惑了}

同理不僅在內(nèi)部,在參數(shù)列表里也是:

template <typename T>void f(const T& t, typename T::const_iterator cit){
   //T不是嵌套從屬名稱,而T::const_iterator是,所以要在T::const_iterator前面加上typename    //....}

2、是嵌套從屬名稱但不用加typename的兩種情況
基類列表(base list)和成員初始化列表(member initializaiton list)
 
template <typename T>class Derived: public Base<T>::Nested {         //基類列表中不允許使用typenamepublic:
  explicit Derived(int x): Base<T>::Nested(int x){  //初始化列表中不允許使用typename    typename Base<T>::Nested temp;         //嵌套從屬名稱(既不在基類列表中又不在初始化列表中)前面必須要加typename  }
}

上一篇:桶排序算法的理解及C語(yǔ)言版代碼示例

欄    目:C語(yǔ)言

下一篇:C語(yǔ)言實(shí)現(xiàn)xml構(gòu)造解析器

本文標(biāo)題:C++的template模板中class與typename關(guān)鍵字的區(qū)別分析

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2198.html

網(wǎng)頁(yè)制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語(yǔ)言數(shù)據(jù)庫(kù)服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有