為什麼不特化函式模板

2021-04-12 17:31:46 字數 1186 閱讀 1490

1. c++ 中主要有哪兩種形式的模板,它們分別如何進行特化?

c++中有類模板與函式模板之分。這兩種模板的工作方式並不完全一樣,最明顯的區別在於過載,普通c++類是不能過載的,因此類模板也不能夠過載。另一方面,普通的c++函式如果名字相同(且函式簽名不同)就會發生過載,因而函式也允許過載。 此外類模板可以被偏特化或全特化。函式模板則只能被全特化,不過,由於函式模板可以被過載,所以我們通過過載也能夠達到類似偏特化的效果。 

準則:記住,函式模板不能偏特化,只能過載。寫乙個看似函式模板偏特化的函式模板實際上是在寫乙個單獨的主函式模板。

以下介紹在不同情況下哪個函式將會被呼叫:

1。非模板函式是c++中的一等公民。如果乙個普通的非模板函式跟乙個函式模板在過載解析的引數匹配中表現一樣好的話,編譯器會選擇普通函式

2。如果編譯器發現沒有合適的「一等公民」可選的話,那麼主函式模板作為c++中的二等公心就會被納入考慮。具體選擇哪個主函式模板則取決於哪 個引數型別匹配得最好。如果還不能決定可以根據以下準則再進一步選擇

(1)如果顯而易見存在乙個「最特化「的主函式模板的話,該主函式模板就會被選中,如果這個被選中的主函式模板碰巧又針對所使用的模板實參做了特化的話,該特化版本就會被編譯器選中,否則編譯器將使用以正確的型別例項化主模板。

(2)否則,如果有兩個或多個」最特化「的主函式模板下相互之間不能分出那個最好的話,呼叫就是二義性的,因為編譯器不能確定它們中哪個是更好的匹配。

(3)否則,如果沒有任何主函式模板可以匹配呼叫的話,呼叫就是錯誤的。

例:template//(a) 乙個主模板

void f(t);

template

void f(t*)   //(b)  乙個主模板,過載了(a): 由於函式模板不能被偏特休,所以只能用過載來代替

template

void f(int *);   //(c) : (b) 的乙個顯式特化

int *p;

f(p);  //呼叫 (c)

template//(a) 乙個主模板

void f(t);

template<>

void f(int *)   //(c)  顯式特化,這次是對(a)進行特化

template

void f(t *) //(b) :第二個主模板,過載了(a)

int *p;

f(p);  //呼叫 (b)

因為函式特化並不參加過載

為什麼不特化函式模板

1.c 標準規定,函式模板不能偏特化 2.函式模板的特化並不參與過載決議 非模板函式是c 的一等公民 如果編譯器沒有發現合適的一等公民,那麼主函式模板作為c 中的二等公民被納入考慮 如果還不能選出唯一的主函式模板,編譯器會根據一組相當晦澀的規則確定出那個主函式模板是最特化的 函式模板特化並不參與過載...

函式模板的特化

函式模板的特化 該定義中乙個或多個模板形參的實際型別或實際值是指定的。特化形式如下 關鍵字template後面接一對空的尖括號 再接模板名和一對尖括號,及括號中指定這個特化定義的模板形參 函式形參表 函式體 template int compare const char const v1,const...

函式模板的特化

include include using namespace std 泛型版本 template int compare const t v1,const t v2 為實參型別 const char 提供特化版本 template int compare const char const v1,c...