C Templates 特化與過載

2021-05-11 08:55:44 字數 1356 閱讀 5782

過載函式模板:

f生成的過載集包含兩個函式:f(int*)和f(int**)。

f生成的過載集包含兩個函式:f(int)和f(int*)。

呼叫實參(int*)0的型別是int*,因此,兩次呼叫都會匹配到f(int*)。

原則上,下面的模板和它們的例項化體可以在同個程式中同時存在:

不過f1('a', 'b');這樣的呼叫就會產生二義性。

只有在f1這兩個模板出現在不同的翻譯單元時,它們的兩個例項化體才可以在同個程式中同時存在。

顯式特化:

全域性的類模板特化:

引入全域性特化需要用到下面3個標記序列:template、< 和 >。

全域性特化的實現並不需要與泛型實現有任何關聯,這就允許可以包含不同名稱的成員函式。實際上,全域性特化只和類模板的名稱有關聯。

應該使用位於類外部的普通成員定義語法來定義全域性類模板特化的成員,也就是說不能指定template<>字首。

全域性模板特化和由模板生成的例項化版本不能夠共存於同乙個程式中:

全域性的函式模板特化:

與類模板特化的區別在於:函式模板特化引入了過載和實參演繹兩個概念

全域性函式模板特化不能包含預設的實參值:

template<> int f(int, int = 35)

對於非內聯的全域性函式模板特化而言,在同個程式中它的定義只能出現一次,仍然必須確保:全域性函式模板特化的宣告必須緊跟在模板定義的後面,以避免試圖使用乙個由模板直接生成的函式。

另一種解決方案是把這個特化宣告為內聯函式,在這種情況下,該函式的定義就可以放在標頭檔案中。

全域性成員特化:

實現特化的語法要求給每個外圍類模板加上template<>字首,如果同時要對乙個成員模板進行特化,還必須加上另乙個template<>字首來說明該宣告表示的是乙個特化:

template<>

template<>

class outer::inner;

};區域性的類模板特化:

表示乙個區域性特化的語法包括:乙個模板引數列表宣告和在類模板名稱後面指定的模板實參列表

區域性特化宣告的引數列表和實參列表的一些約束:

類模板區域性特化的引數個數是可以和基本模板不一樣的

例:針對指向成員指標的指標

小結:

類模板特化和函式模板過載的區別:

對於特化,在看到乙個呼叫時,只會查詢基本模板,在後來需要決定呼叫哪乙個實現的時候才會考慮具體的特化模板。

對於過載函式模板進行查詢的時候,所有的過載函式模板都必須放入過載集裡面,而且這些過載函式模板還可以來自不同的名字空間和類。

選特化還是過載

乙個函式模板即有特化版又有過載版,編譯器會選哪個?以下 來自 為什麼不要特化函式模版 的例3 1 include iostream 23 using namespace std 45 template class t 6void f t 710 11template 12void f int 131...

模板函式 過載 特化

見 12 3456 78910 1112 1314 1516 1718 1920 2122 2324 2526 2728 2930 3132 3334 3536 3738 3940 4142 4344 4546 4748 4950 5152 5354 5556 5758 5960 6162 6364...

特化與偏特化

綜合stl 原始碼剖析中給出的兩種定義,可以如下定義 所謂偏特化的意思是提供另乙份更進一步條件的template定義式,其仍然是模板化的。舉乙個例子 templatestruct test 偏特化版本1 templatestruct test 偏特化版本2 templatestruct test t...