所謂模板,就是模板,但與我們所熟知的模子不同,模板用於生成不同的東西(函式或者類)。在c++中有函式模板和類模板。今天我們來**一下函式模板。
場景:我們需要乙個函式來做加法運算又或者我們需要自己實現print函式,那怎麼處理傳入引數不同(double ? int ? char ? short ? string ?)的情況呢?你或許會脫口而出「函式過載」,但這意味著你至少要寫兩個以上的函式去支援你的引數型別和個數的變化,right?而且這種做法不支援擴充套件,如果有其他的需求,就必須再增加過載函式,這是比較愚蠢的,相信你也這麼認為。那麼,更好的辦法是什麼呢?函式模板。
我們來看例子?
1 template //先宣告模板引數 t2 typename t add(const t &num1, const t &num2)//定義模板函式,注意引數的型別36
7int
main()
8
這樣一來,我們就實現了乙個模板,多種引數型別,從這樣說來,模板是優於函式過載的。那麼,使用他的時候,編譯器做了哪些工作呢?
1. 編譯模板本身時, 檢查語法資訊;?還記得auto和decltype嗎? 這裡的實參推斷與他們類似。如上面例子中的add(1, 3),我們的實參就是int型,那麼編譯器就會將int型繫結到我們的模板型別t上,這樣一來,模板就例項化成了2. 模板使用時,檢查引數型別是否匹配,數目正確與否;
3. 例項化時,進行實參推斷。
int add(const int &num1, const int &num2)好處是,編譯器自己進行引數型別推斷,生成函式例項,無需人為參與,也避免了,函式過載的**堆砌。(personal thought)一些我們使用已久的函式不就是這樣嗎?sort(),find(),reverse()...
下面我們討論一下,模板的(全)特例化與偏特例化。
全特化所謂特例化,就是將引數定死。它本質上是模板的乙個特例。比如:
templete <>//標識我們在特例化模板double add(constdouble&d1, constdouble&d2)//引數型別具體化
這裡我們就接管了部分編譯器的工作,如果同時存在模板和特例化模板, 當我們使用模板(引數與特例化一致),編譯器會優先選擇特例化模板例項(至少避免了型別推斷不是嗎?)當我們有更好更直接的函式時,要毫不猶豫地使用它。(比如:我們對傳入引數所知甚少時,就要盡量「包住「所有的可能輸入;而當我們明確知道引數型別和數量時,就應該特化它,提高效率)
偏特化偏特化是指,特化部分引數(個數特化)或者引數型別(範圍特化)。
個數特化:將幾個引數型別具體化
1 template 2 typename t add(const t &num1, const int &num2)//特化乙個引數 為int3
範圍特化:將引數限定在某個範圍內(指標、const ...)
1 template 2 typename t add(constint num1, const t &num2)//將乙個引數特化為 const int
3
1 template 2 typename t add(constint* num1, const t &num2)//
將乙個引數特化為 const int* 指標
3
至於是否進行特例化,就要自己想想了。
1. 某些傳入引數沒有和其他引數一樣的特性(算術或者邏輯),我們就需要為它量身定製乙個模板例項;(就好比add()例子中,要加和string怎麼辦?它可是字元陣列呀。)
2. 某些引數我們是可以確定的,就可以特例化,以期更高的效率(避免型別推導和生成例項)。
類模板更為複雜,可以參考這裡
c 函式模板
include using namespace std template t max t a,t b,t c int main int main int i1 185,i2 76,i3 567,i double d1 56.63,d2 90.23,d3 3214.78,d long g1 67854...
c 函式模板
關鍵字template總是放在模板的電腦關於與宣告的最前面,關鍵字後面是用逗號分隔的模板參數列,該列表是模板參數列,不能為空。模板引數可以是乙個模板型別引數,它代表了一種型別 也可以是乙個模板非型別引數,它代表了乙個常量表示式。模板型別引數由關鍵字class或typename後加乙個識別符號構成。在...
C 函式模板
c 提供了函式模板 function template 所謂函式模板,實際上是建立乙個通用函式,其函式型別和形參型別不具體指定,用乙個虛擬的型別來代表。這個通用函式就稱為函式模板。凡是函式體相同的函式都可以用這個模板來代替,不必定義多個函式,只需在模板中定義一次即可。在呼叫函式時系統會根據實參的型別...