編譯器對待模版時,總會用它產生特定型別的版本,這個過程成為例項化。其中函式模板在呼叫時或者用它對指向函式的指標初始化或者賦值時例項化,類模板在引用實際模板型別時例項化。尤其對於函式模板,編譯器通常會進行實參的推斷。伴隨而來的問題跟函式過載類似,就是確定匹配的模板。
對於模板,多個型別的實參必須完全匹配,不能依靠隱式的型別轉換:
對於模板:
template int compare(const t &v1,const t &v2)
其中兩個型別形參的型別是完全相同的,則不能呼叫:
short si = 10;
int ival = 100;
//不存在實參型別轉化
cout<
這裡不存在自動型別轉換。如果你非要用兩個不同型別的作比較,只能使用兩個模板形參:
template int compare(const t1 &v1,const t2 &v2)
但是,型別轉化也有例外:
1.const轉換:如果函式的形參是const引用或者指標,那麼如果採用非const物件的引用或者指標也能呼叫。這取決於const變數的初始化規則:我們可以使用非const的型別初始化乙個對應的const型別的引用。如果函式接受的是非引用型別,形參和實參都會忽略const。同樣是因為我們可以給乙個非const變數傳遞乙個const值來初始化。
template int fobj(t,t);
template int fref(const t&,const t&);
string s1 = "a vaule";
const string s2 = "another value";
//const被忽略
fobj(s1,s2);
//s1轉化為const引用
fref(s1,s2);
2.陣列或者函式到指標的轉換:如果形參不是引用型別,則陣列或者函式型別的實參轉換為對應的指標:陣列轉換為指向陣列的第乙個元素,函式轉換為指向函式的指標。
int a[2] ;
int b[42];
int c[2] ;
fobj(a,b);
//錯誤:矩陣型別不匹配
//fref(a,b);
fref(a,c);
當使用引用時,陣列並不轉化為指標,陣列的元素個數也作為矩陣的型別是否相同的衡量標準之一。
有些時候,我們並不能推斷模版實參的型別(在函式返回值型別與形參列表中的所有型別都不同時,容易出現這種問題),此時我們必須顯式的指定模板形參所用的型別或值。
舉乙個例子:比如,我們想對兩個數(比如整形+浮點型)以任意順序求和。那麼返回值應該如何設計呢?
我們將返回值的型別也設計成模板形參。
template t1 sum(const t2 &val1,const t3 &val2)
但這就存在乙個問題,編譯器無法推斷返回值的型別到底是什麼。所以在呼叫這個模板時,必須顯式指定返回值的型別:
cout<(1,2.2)<(1,2.2)<
這兩句將得出不同的結果,因為它們的返回值分別為double和int型。
模板例項化
c 中模板的例項化指函式模板 類模板 生成模板函式 模板類 的過程。對於函式模板而言,模板例項化之後,會生成乙個真正的函式。而類模板經過例項化之後,只是完成了類的定義,模板類的成員函式需要到呼叫時才會被初始化。模板的例項化分為隱式例項化和顯示例項化。1 中文名模板例項化 外文名template in...
template模板及模板類的例項化
通常,當我們呼叫乙個函式時,編譯器只需要掌握函式的宣告。類似的,當我們使用乙個類型別的物件時,類定義必須是可用的,但成員函式的定義不必已經出現。因此我們將類定義和函式宣告放在標頭檔案中,而普通函式和類的成員函式的定義放在原始檔中。模板則不同 為了生成乙個例項化版本,編譯器需要掌握函式模板或類模板成員...
ue4 模板類例項化 關於模板類例項化
模板函式在宣告的時候,其實並不存在,函式位址也就無從談起了,而匯出到 動態鏈結庫不能將模板類匯出,因為沒法生成例項 如果把模板類的宣告和定義都放在標頭檔案中。需要用到模板類的時候,只需要包 含該標頭檔案,然後進行例項化。如果模板類的宣告和定義分別放在標頭檔案和原始檔中。當例項化的時候,只包含標頭檔案...