模板是c++支援引數化多型的工具,使用模板可以使使用者為類或者函式宣告一種一般模式,使得類中的某些資料成員或者成員函式的引數、返回值取得任意型別。
模板是一種對型別進行引數化的工具;
通常有兩種形式:函式模板和類模板;
函式模板針對僅引數型別不同的函式;
類模板針對僅資料成員和成員函式型別不同的類。
使用模板的目的就是能夠讓程式設計師編寫與型別無關的**。比如編寫了乙個交換兩個整型int 型別的swap函式,這個函式就只能實現int型,對double,字元這些型別無法實現,要實現這些型別的交換就要重新編寫另乙個swap函式。使用模板的目的就是要讓這程式的實現與型別無關,比如乙個swap模板函式,即可以實現int型,又可以實現double型的交換。模板可以應用於函式和類。下面分別介紹。
注意:模板的宣告或定義只能在全域性,命名空間或類範圍內進行。即不能在區域性範圍,函式內進行,比如不能在main函式中宣告或定義乙個模板。
一.函式模板
1、函式模板的格式:
template
形參名,class
形參名,......>返回型別 函式名(引數列表)
其中template和class是關見字,class可以用typename關見字代替,在這裡
typename 和class沒區別,<>括號中的引數叫
模板形參,模板形參和函式形參很相像,模板形參不能為空
。一但宣告了模板函式就可以用模板函式的形參名宣告類中的成員變數和成員函式,即可以在該函式中使用內建型別的地方都可以使用模板形參名。模板形參需要呼叫該模板函式時提供的模板實參來初始化模板形參,一旦編譯器確定了實際的模板實參型別就稱他例項化了函式模板的乙個例項。比如swap的模板函式形式為
template void swap(t& a, t& b){},
當呼叫這樣的模板函式時型別t就會被被呼叫時的型別所代替,比如swap(a,b)其中a和b是int型,這時模板函式swap中的形參t就會被int所代替,模板函式就變為swap(int &a, int &b)。而當swap(c,d)其中c和d是double型別時,模板函式會被替換為swap(double &a, double &b),這樣就實現了函式的實現與型別無關的**。
2、注意:對於函式模板而言不存在h(int,int)這樣的呼叫,不能在函式呼叫的引數中指定模板形參的型別,對函式模板的呼叫應使用實參推演來進行,即只能進行h(2,3)這樣的呼叫,或者int a, b; h(a,b)。
二.類模板
1、類模板的格式為:
template
形參名,class
形參名,…> class
類名;
類模板和函式模板都是以template開始後接模板形參列表組成,模板形參不能為空,一但宣告了類模板就可以用類模板的形參名宣告類中的成員變數和成員函式,即可以在類中使用內建型別的地方都可以使用模板形參名來宣告。比如
templateclass a;
在類a中宣告了兩個型別為t的成員變數a和b,還宣告了乙個返回型別為t帶兩個引數型別為t的函式hy。
2、類模板物件的建立:比如乙個模板類a,則使用類模板建立物件的方法為am;在類a後面跟上乙個<>尖括號並在裡面填上相應的型別,這樣的話類a中凡是用到模板形參的地方都會被int所代替。當類模板有兩個模板形參時建立物件的方法為am;型別之間用逗號隔開。
3、對於類模板,模板形參的型別必須在類名後的尖括號中明確指定。比如a<2> m;用這種方法把模板形參設定為int是錯誤的(編譯錯誤:error c2079: 'a' uses undefined class 'a'),類模板形參不存在實參推演的問題。也就是說不能把整型值2推演為int型傳遞給模板形參。要把類模板形參調置為int型必須這樣指定am。
4、在類模板外部定義成員函式的方法為:
template
《模板形參列表》 函式返回型別 類名《模板形參名》::函式名(引數列表),
比如有兩個模板形參t1,t2的類a中含有乙個void h()函式,則定義該函式的語法為:
templatevoid a::h(){}。
注意:當在類外面定義類的成員時template後面的模板形參應與要定義的類的模板形參一致。
三.使用
模板的實現和宣告是可以分離的,前提是你要把宣告和實現的標頭檔案都引用進去。
比如你可以寫乙個.hpp(為什麼要是hpp呢,因為寫成hpp你就可以在cpp中把這個檔案也包含進去)
test.h:
#includeusing namespace std;
class test;
test.hpp:
#include "test.hpp"
templatevoid test::compare(const t& v1, const t& v2)
在其他用到這個類的地方,把這個兩個檔案都include進去就可以使用這個類了。
疑問:看到乙個地方類中定義了乙個模板函式如下:
它這個模板函式,帶兩個模板形參,但是他呼叫的時候卻只需要指定乙個形參,也可以用?
bool result = thread.invoke(&myfunctionreturningbool);
我暫時的理解是,invoke這個bool是指定的returnt的type,然後functort的type是由傳入引數myfunctionreturningbool推演出的。
參考:
C 中map模板的用法
std map用法 stl是標準c 系統的一組模板類,使用stl模板類最大的好處就是在各種c 編譯器上都通用。在stl模板類中,用於線性資料儲存管理的類主要有vector,list,map 等等。本文主要針對map物件,結合自己學習該物件的過程,講解一下具體用法。本人初學,水平有限,講解差錯之處,請...
C 模板程式設計之typename用法
例子來自 effective c 第三版 模板程式設計主要是編譯器在大發神威。模板函式基礎用法 typename用法 在展示上篇日誌結尾的遺留的問題前,先來說明模板程式設計中template宣告式中class和typename的關係。什麼是template宣告式?就是如下的語句 template觀察...
c 中pair類模板的用法詳解
pair 標頭檔案 include 類模板 template struct pair 引數 t1是第乙個值的資料型別,t2是第二個值的資料型別。功能 pair將一對值組合成乙個值,這一對值可以具有不同的資料型別 t1和t2 兩個值可以分別用pair的兩個公有函式first和second訪問。具體用法...