C語言的模板與泛型編程你了解嗎_第1頁
C語言的模板與泛型編程你了解嗎_第2頁
C語言的模板與泛型編程你了解嗎_第3頁
C語言的模板與泛型編程你了解嗎_第4頁
C語言的模板與泛型編程你了解嗎_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第C語言的模板與泛型編程你了解嗎目錄模板與泛型編程淺談?wù)?EffectiveC++):模板與泛型編程簡單介紹函數(shù)模板模板編譯類模板為什么我們需要模板特例化?總結(jié)

模板與泛型編程淺談

摘要(EffectiveC++):

?C++template的最初發(fā)展動機(jī)很直接:讓我們得以建立類型安全的容器如vector,list和map。然而當(dāng)愈多人用上templates時,他們發(fā)現(xiàn)template有能力完成愈多可能的變化。容器當(dāng)然很好,但泛型編程(genericprogramming)寫出的代碼和其所處理的對象類型彼此獨(dú)立更好。STL算法如for_each,find和merge就是這一類編程的結(jié)果。最終人們發(fā)現(xiàn),C++template機(jī)制自身是一部完整的圖靈機(jī):它可以用來計(jì)算任何可計(jì)算的值。于是導(dǎo)出了模板元編程(templatemataprogramming),創(chuàng)造出在C++編譯器內(nèi)執(zhí)行并于編譯完成時停止執(zhí)行的程序。

模板與泛型編程簡單介紹

?面向?qū)ο缶幊蹋∣OP)和泛型編程都可以處理編寫程序時不知道類型的情況;二者的不同之處在于:OOP能處理類型在程序運(yùn)行之前都未知的情況;而在泛型編程中,在編譯時就能獲知類型了

?我們所常用的STL標(biāo)準(zhǔn)庫中,每一個容器都提供了單一的,泛型的定義,例如我們所常用的vector,我們可以定義很多類型的vector

vectorint//vi是裝載int類型的vector容器的實(shí)例

vectorstring//vs是裝載string類型的vector容器的實(shí)例

vectordouble//vd是裝載double類型的vector容器的實(shí)例

模板是泛型編程的基礎(chǔ),一個模板就是一個創(chuàng)建類或者函數(shù)的藍(lán)圖或者公式

函數(shù)模板

//簡單的比較函數(shù)模板

templatetypenameT

intcmp(constTv1,constTv2){

if(v1v2)

return-1;

elseif(v1v2)

return1;

else

return0;

函數(shù)定義以關(guān)鍵字template開始,后跟一個模板參數(shù)列表,這是一個逗號分隔的一個或多個模板參數(shù)的列表,用尖括號包圍起來

**注:**在模板定義中,模板參數(shù)列表不能為空

模板參數(shù)列表表示在類或函數(shù)定義中用到的類型或者值。當(dāng)我們使用模板的時候,我們可以(顯式或隱式地)指定模板實(shí)參,將其綁定到模板參數(shù)上

簡單了解模板的實(shí)例化過程

?眾所周知,當(dāng)你覺得模板編程十分智能的時候,一定是有東西在為你負(fù)重前行,C++提供了模板與泛型編程的這個能力,這便意味著有一個東西在為你動態(tài)地實(shí)現(xiàn)模板的功能,而這一定是比C++這個高級語言層面更為底層的東西,而我們所了解的知識中,比C++高級語言較為底層的東西,除了操作系統(tǒng),便是編譯器了。

?當(dāng)我們調(diào)用一個函數(shù)模板的時候,編譯器(通常)用函數(shù)實(shí)參來為我們推斷模板實(shí)參。簡單來講,便是我們在調(diào)用函數(shù)模板的時候,編譯器通過使用實(shí)參的類型來確定綁定到模板參數(shù)T的類型

coutcmp(1,0)endl;//T為int

在上訴代碼中,函數(shù)cmp的實(shí)參類型是int,編譯器便會推斷出模板實(shí)參為int,并將它綁定到模板參數(shù)T上

簡單來說,編譯器用推斷出的模板參數(shù)來為我們實(shí)例化一個特定版本的函數(shù)

模板編譯

當(dāng)編譯器遇到一個模板定義的時候,它并不會生成代碼。只有我們實(shí)例化出模板的一個特定的版本時,編譯器才會生成其對應(yīng)的代碼。當(dāng)我們使用(而不是定義)模板時,編譯器才會生成代碼。這個特性影響我們?nèi)绾谓M織代碼以及錯誤何時才可以被檢測到

通常來說,我們將類定義和函數(shù)說明放在頭文件中,而普通函數(shù)和類的成員函數(shù)的定義放在源文件中

模板則不盡相同:為了生成一個實(shí)例化的版本,編譯器需要掌握函數(shù)模板或類模板成員函數(shù)的定義

總結(jié):與非模板代碼不同,模板的頭文件通常既包括聲明也包括定義,即函數(shù)模板和類模板成員函數(shù)的定義通常放在頭文件中

大多數(shù)編譯錯誤出現(xiàn)的時機(jī)

第一階段,編譯模板本身時,該時期所出現(xiàn)的錯誤大多數(shù)為語法錯誤第二階段,編譯器遇到模板使用時第三階段,模板實(shí)例化時,而只有在這個階段才能發(fā)現(xiàn)類型相關(guān)的問題

**注意事項(xiàng):**保證傳遞給模板的實(shí)參支持模板所要求的操作,以及這些操作在模板中能正確的工作,是調(diào)用者的責(zé)任

類模板

?類模板是用來生成類的藍(lán)圖的。與函數(shù)模板不同之處是,編譯器不能為類模板推斷模板參數(shù)類型。所以我們必須在模板名后的尖括號中提供額外的信息用來替代模板參數(shù)的模板實(shí)參列表

vectorint

dequedouble

pairstring,intkey_val;

定義類模板

templatetypenameT

classT_vector{

public:

typedefTvalue_type;

//構(gòu)造函數(shù)

T_vector()=default;

T_vectot(std::initializer_listTil);

//容器的元素?cái)?shù)目

size_typesize()const{returndata-size();}

boolempty()const{returndata-empty();}

//添加元素

voidpush_back(constTval){

data-push_back(val);

voidpush_back(Tval){

data-push_back(std::move(val));

private:

std::shared_ptrstd::vectorTdata;

//若data[i]無效,則拋出msg

voidcheck(size_typei,conststd::stringmsg)const;

類似函數(shù)模板,類模板以關(guān)鍵字template開始,后跟模板參數(shù)列表。在類模板(及其成員)的定義中,我們將模板參數(shù)當(dāng)作替身,代替使用模板時用戶需要提供的類型或值

**注:**一個類模板的每一個實(shí)例都形成一個獨(dú)立的類,而類模板的每個實(shí)例都有其自己版本的成員函數(shù)

?所以,我們可能會出現(xiàn)一個單一模板并不能滿足所有類型的需求,而模板特例化就出現(xiàn)了

類模板成員函數(shù)的實(shí)例化

?默認(rèn)的情況下,一個類模板的成員函數(shù)只有在程序用到它的時候才會實(shí)例化

//實(shí)例化T_vector和接受initializer_listint的構(gòu)造函數(shù)

T_vectorintT_vi={0,1,2,3,4,5};

如果一個成員函數(shù)沒有被使用,則它將不會被實(shí)例化

為什么我們需要模板特例化?

當(dāng)我們編寫單一的模板時,使其對任何可能的模板實(shí)參都是最合適的,都能實(shí)例化,但者往往都是過于理想化的情況。在某些特殊的情況下,通用的模板的定義可能對特定的類型是不合適的,通用定義的模板可能會出現(xiàn)編譯失敗或者做得不夠完善的情況。

?故,當(dāng)我們不能(或者不希望)使用模板版本的時候,可以定義類或函數(shù)模板的一個特例化版本

定義函數(shù)模板特例化

//原先cmp函數(shù)的特殊版本,用來處理特殊的字符數(shù)組的指針templateintcmp(constchar*constp1,constchar*constp2){returnstrcmp(p1,p2);}//原先cmp函數(shù)的特殊版本,用來處理特殊的字符數(shù)組的指針

template

intcmp(constchar*constp1,constchar*constp2){

returnstrcmp(p1,p2);

函數(shù)重載與模板特例化的區(qū)別

?當(dāng)定義函數(shù)模板的特例化版本時,我們本質(zhì)上接管了編譯器的工作。即,我們?yōu)樵鹊哪0宓钠渲幸粋€特殊的實(shí)例提供了定義。簡而言之,特例化的本質(zhì)是實(shí)例化一個模板,而非重載它,因此特例化并不影響函數(shù)匹配

注意事項(xiàng):

為了特例化一個模板,原模版的聲明必須在作用域中在任何使用模板實(shí)例的代碼之前,特例化版本的聲明也必須在作用域中所有同名模板的聲明應(yīng)該放在前面,然后是

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論