C 11 函式模板的預設模板引數

2022-06-02 10:39:10 字數 2100 閱讀 3650

類模板:通用的類描述(使用泛型來定義類),進行例項化時,其中的泛型再用具體的型別替換。

函式模板:

通用的函式描述(使用泛型來定義函式),進行例項化時,其中的泛型再用具體的型別替換。

c++98標準中兩者的區別

函式模板和類模板在c++98標準中一起被引入,兩者區別主要在於:

在類模板宣告時,標準允許其有預設模板引數。而函式模板卻不支援。

預設模板引數的作用如同函式的預設形參。

不過在c++11中,這一限制已經被解除了,如下例所示:

1

void defparm(int m = 3) {} //

c++98編譯通過,c++11編譯通過

23 template int>

4class defclass {}; //

c++98編譯通過,c++11編譯通過

56 template int>

7void deftempparm() {}; // c++98編譯失敗,c++11編譯通過

可以看到,deftempparm函式模板擁有乙個預設模板引數(型別int)。

使用僅支援c++98的編譯器編譯,deftempparm的編譯會失敗,而支援c++11的編譯器則無問題。

c++11標準中兩者的區別

儘管c++11支援了函式模板的預設模板引數,不過在語法上,兩者還是存在區別:

類模板在為多個預設模板引數宣告指定預設值時,必須遵照「從右往左」的規則進行指定。

而這個規則對函式模板來說並不是必須的。示例如下:

1 template int>

2class

defclass1 {};

34 template int, typename t2>

5class defclass2 {}; //

error: 無法通過編譯:因為模板引數的預設值沒有遵循「由右往左」的規則

67 template int i = 0>

8class

defclass3 {};

910 template

11class defclass4 {}; //

error: 無法通過編譯:因為模板引數的預設值沒有遵循「由右往左」的規則

1213 template int, typename t2>

14void deffunc1(t1 a, t2 b) {}; //

ok 函式模板不用遵循「由右往左」的規則

1516 template

17void deffunc2(t a) {}; //

ok 函式模板不用遵循「由右往左」的規則

可以看到,不按照從右往左定義預設類模板引數的模板類defclass2和defclass4都無法通過編譯。

而對於函式模板來說,預設模板引數的位置則比較隨意。

deffunc1和deffunc2都為第乙個模板引數定義了預設引數,而第二個模板引數的預設值並沒有定義,c++11編譯器卻認為沒有問題。

函式模板的引數推導規則也並不複雜。簡單地講:如果能夠從函式實參中推導出型別的話,那麼預設模板引數就不會被使用,反之,預設模板引數則可能會被使用。

如下示例:

1 template 

2void f(t t = 0, u u = 0

) {};

3void

g()

4

定義了乙個函式模板f,f同時使用了預設模板引數和預設函式引數。

可以看到,由於函式的模板引數可以由函式的實參推導而出:

在f(1)這個函式呼叫中,例項化出了模板函式的呼叫應該為f(1, 0),其中,第二個型別引數u使用了預設的模板型別引數double,而函式實參則為預設值0。

類似地,f()例項化出的模板函式第二引數型別為double,值為0。

而表示式f()由於第一型別引數t的無法推導,從而導致了編譯的失敗。

而通過這個例子也可以看到,預設模板引數通常是需要跟預設函式引數一起使用的。

還有一點應該注意:模板函式的預設形參值不是模板引數推導的依據。函式模板引數的選擇,終究是由函式的實參推導而來的。

good good study, day day up.

順序 選擇 迴圈 總結

C 11之模板別名 函式模板的預設模板引數

在c 98 03裡,我們可以通過typedef 關鍵字定義乙個型別的別名,比如 typedef unsigned int uint t 在這裡我們定義了unsigned int型別的別名和uint t,在以後需要使用unsigned int的時候我們都可以用uint t替換,但是uint t僅僅是作...

C 11 模板函式的預設模板引數

一 深入理解c 11 裡的兩句話 c 98中,引入了函式模板和類模板,允許模板類宣告的時候有預設模板引數,但是不支援函式模板。c 11 開始支援,區別是模板函式的預設模板引數不需要 從右往左 依次指定。特別,模板引數的預設形參不是模板引數推導的依據。二 include 模板類的預設模板引數的順序從右...

C 11可變引數函式模板

在log時引數是型別和個數是不固定的,所以在做log函式時,很多煩惱,不過c 11給我們帶來的希望 include include using namespace std class logger static void makeloggeroff static bool loggerstate t...