柚子快報(bào)邀請碼778899分享:模板進(jìn)階【C++】
柚子快報(bào)邀請碼778899分享:模板進(jìn)階【C++】
文章目錄
模板的特殊化函數(shù)模板特化的作用
函數(shù)模板的的特殊化語法:函數(shù)模板特化的要求
類模板的特殊化類模板的特殊化的要求類模板的特殊化的語法全特化偏特化實(shí)例化部分模板參數(shù)對基本類模板(母板)的模板參數(shù)進(jìn)行限制
非類型模板參數(shù)非類型模板參數(shù)的特點(diǎn)(注意點(diǎn))
模板的特殊化
模板的特化是對已經(jīng)存在的模板進(jìn)行的特殊處理
通常情況下,使用模板可以實(shí)現(xiàn)一些與類型無關(guān)的代碼,但對于一些特殊類型的可能會(huì)得到一些我們不想要的結(jié)果需要特殊處理
例如 寫一個(gè)比較函數(shù),如果是直接寫成下圖的函數(shù)模板,我們就只能按照規(guī)定好的大小比較方式進(jìn)行比較
上圖的比較雖然按照語法來說是正確的
但是如果我們想寫一個(gè)當(dāng)傳入的參數(shù)的類型是int*的時(shí)候,比較的方式是指針解引用之后再比較的話,如果只有上圖中的模板就做不到了
這個(gè)時(shí)候就可以對特殊化出一個(gè)模板,專門處理我們的特殊要求 可以看到,這樣就完成了我們的對int*類型特殊處理的要求
函數(shù)模板特化的作用
作用很簡單: 傳入的具體類型如果擁有對應(yīng)的特化模板函數(shù),就會(huì)優(yōu)先調(diào)用那個(gè)特化的模板函數(shù)
例如上面舉例的比較大小的模板函數(shù)Greater,如果傳給Greater的參數(shù)類型是int*,那就會(huì)優(yōu)先調(diào)用int*特化的模板函數(shù)
因?yàn)楹瘮?shù)模板特化的作用基本只有這個(gè),所以其實(shí)函數(shù)模板的特化是有替代的,那就是普通的函數(shù)沒錯(cuò)就是普通的函數(shù),模板初階【模板初階【C++】】中就說過,如果既有函數(shù)模板又有普通函數(shù)時(shí),在傳遞參數(shù)都不會(huì)類型轉(zhuǎn)換的情況下,編譯器就會(huì)優(yōu)先調(diào)用普通函數(shù)
例
所以其實(shí)函數(shù)模板的特化其實(shí)挺雞肋的,因?yàn)橹苯訉懗善胀ê瘮?shù)還更好
因?yàn)樗恼Z法限制比普通函數(shù)多在函數(shù)模板特化和普通函數(shù)共存時(shí),甚至還會(huì)優(yōu)先調(diào)用普通函數(shù)
但是類模板的特化就有用得多了
函數(shù)模板的的特殊化
語法:
template<>
返回值 函數(shù)名<具體類型,具體類型,……>(參數(shù)表)
{
函數(shù)體
}
例 具體類型就是要特殊處理的類型【特化類型】
函數(shù)模板特化的要求
因?yàn)槟0宓奶鼗菍σ呀?jīng)存在的模板進(jìn)行的特殊處理 所以必須要先有一個(gè)基礎(chǔ)的函數(shù)模板(母板),才能對這個(gè)模板進(jìn)行特殊化關(guān)鍵字template后面的尖括號<>里面一定得是空的,這是語法規(guī)定,不是空的就報(bào)錯(cuò) 特化的模板函數(shù)的參數(shù)表: 必須要和基礎(chǔ)的函數(shù)模板(母板)的參數(shù)完全相同 人話:寫出來的特化的模板函數(shù)的參數(shù)表,與把特化類型傳給基礎(chǔ)的函數(shù)模板(母板)后實(shí)例化出來的模板函數(shù)的參數(shù)表一樣 不然可能會(huì)出現(xiàn)很多奇怪的錯(cuò)誤,此時(shí)要是實(shí)在解決不了,就直接實(shí)現(xiàn)成全局函數(shù)就行了
類模板的特殊化
類模板的特殊化的要求
因?yàn)椋耗0宓奶鼗菍σ呀?jīng)存在的模板進(jìn)行的特殊處理
和函數(shù)模板一樣,必須要先有一個(gè)基礎(chǔ)的類模板(母板),才能對這個(gè)類模板進(jìn)行特殊化
類模板的特殊化的語法
template<空 或者 模板參數(shù),模板參數(shù),……>
class 類名<具體類型/加上限制的模板參數(shù)>
{
類體
}
全特化
全特化就是把基本類模板(母板)的模板參數(shù)全部實(shí)例化 例 全特化了之后,當(dāng)傳給類模板的參數(shù)和全特化的模板實(shí)例化的參數(shù)完全相同的時(shí)候,就會(huì)調(diào)用全特化的類模板實(shí)例化對象
如下圖:
偏特化
偏特化分兩種:
實(shí)例化部分模板參數(shù)
這樣偏特化了之后,傳給類模板的參數(shù)和偏特化的類模板部分實(shí)例化的參數(shù)完全相同的時(shí)候,就會(huì)調(diào)用偏特化的類模板進(jìn)行實(shí)例化對象
例 如下圖,當(dāng)傳給A類的模板參數(shù),第一個(gè)是int時(shí)將會(huì)調(diào)研偏特化的類模板實(shí)例化對象 第一個(gè)模板參數(shù)不是int的時(shí)候,才會(huì)調(diào)用基本類模板(母板)進(jìn)行實(shí)例化對象
對基本類模板(母板)的模板參數(shù)進(jìn)行限制
不實(shí)例化基本類模板(母板)的模板參數(shù),而是對它加上限制【加const,*{指針限制},&(引用限制)等】
這樣偏特化了之后,傳給類模板的參數(shù)和偏特化的限制的參數(shù)完全相同的時(shí)候,就會(huì)調(diào)用偏特化的類模板進(jìn)行實(shí)例化對象
例
如下圖,偏特化加上的限制是*{指針限制},所以如果傳給類模板的模板參數(shù)都是指針類型的就會(huì)調(diào)用偏特化的類模板進(jìn)行對象的實(shí)例化 實(shí)例化c對象的時(shí)候傳給類模板的模板參數(shù)都是指針類型,所以調(diào)用了偏特化的類模板 實(shí)例化b對象的時(shí)候傳給類模板的模板參數(shù)只有第一個(gè)是指針類型,并沒有與偏特化的限制的參數(shù)完全相同,所以調(diào)用的還是基本類模板(母板)
非類型模板參數(shù)
非類型參數(shù): 就是用一個(gè)常量作為類模板或者函數(shù)模板的一個(gè)參數(shù),在模板中可將該參數(shù)當(dāng)成常量來使用
例如: 自己封裝一個(gè)靜態(tài)數(shù)組,此時(shí)就可以用非類型模板參數(shù)作為靜態(tài)數(shù)組的容量大小
非類型模板參數(shù)的特點(diǎn)(注意點(diǎn))
C++20以前非類型模板參數(shù)的類型只能是整型或者char類型 C++20以后非類型模板參數(shù)的類型支持所有內(nèi)置類型,但不能是自定義類型 非類型模板參數(shù)可以給缺省值 因?yàn)榉穷愋湍0鍏?shù)是常量,所以它接收的參數(shù)也必須是常量或者是const修飾的變量 例 傳變量就會(huì)報(bào)錯(cuò)
柚子快報(bào)邀請碼778899分享:模板進(jìn)階【C++】
相關(guān)文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。