C++的template模板中class與typename關(guān)鍵字的區(qū)別分析
在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 //....}
基類列表(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ǔ)言實(shí)現(xiàn)xml構(gòu)造解析器
本文標(biāo)題:C++的template模板中class與typename關(guān)鍵字的區(qū)別分析
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2198.html
您可能感興趣的文章
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 01-10c語(yǔ)言求1+2+...+n的解決方法
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
- 01-10深入二叉樹兩個(gè)結(jié)點(diǎn)的最低共同父結(jié)點(diǎn)的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車次數(shù)的問(wèn)題詳解
- 01-10c語(yǔ)言 跳臺(tái)階問(wèn)題的解決方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子