可變參模板template

2022-05-03 11:42:39 字數 3051 閱讀 5556

普通模板只可以採取固定數量的模板引數。然而,有時候我們希望模板可以接收任意數量的模板引數,這個時候可以採用可變引數模板。對於可變引數模板,其將包含至少乙個模板引數包,模板引數包是可以接收0個或者多個引數的模板引數。相應地,存在函式引數包,意味著這個函式引數可以接收任意數量的引數。

乙個可變引數類模板定義如下:

templateclass

tuple

{};

可以用任意數量的型別來例項化tuple:

tuple<>t0;

tuple

t1;tuple

t2;//tuple<0> error; 0 is not a type

如果想避免出現用0個模板引數來例項化可變引數模板,可以這樣定義模板:

templateclass

tuple

{};

此時在例項化時,必須傳入至少乙個模板引數,否則無法編譯。

同樣地,可以定義接收任意引數的可變引數函式模板:

templatevoid

f(types ... args);

cout

<列印可變引數的個數

//一些合法的呼叫

f();f(1

);f(

3.4, "

hello

");

對於類模板來說,可變模板引數包必須是模板引數列表中的最後乙個引數(即模板列表引數中的最後乙個引數必須是可變的)。但是對於函式模板來說,則沒有這個限制,考慮下面的情況:

templateclass

invalid

{};

//這是非法的定義,因為永遠無法推斷出u的型別

template

void valid(u u, ts ... args); //

這是合法的,因為可以推斷出u的型別

//void invalid(ts ... args, u u);

//非法的,永遠無法推斷出u

valid(

1.0, 1, 2, 3); //

此時,u的型別是double,ts是

無法直接遍歷傳給可變引數模板的不同引數,但是可以借助遞迴的方式來使用可變引數模板。可變引數模板允許建立型別安全的可變長度引數列表。下面定義乙個可變引數函式模板processvalues(),它允許以型別安全的方式接受不同型別的可變數目的引數。函式processvalues()會處理可變引數列表中的每個值,對每個引數執行對應版本的handlevalue()。

//

處理每個型別的實際函式

void handlevalue(int value)

void handlevalue(double value)

void handlevalue(string value)

//用於終止迭代的基函式

templatevoid

processvalues(t arg)

//可變引數函式模板

templatevoid

processvalues(t arg, ts ... args)

可以看到這個例子用了三次... 運算子,但是有兩層不同的含義。用在引數模板列表以及函式引數列表,其表示的是引數包。前面說到,引數包可以接受任意數量的引數。用在函式實際呼叫中的...運算子,它表示引數包擴充套件,此時會對args解包,展開各個引數,並用逗號分隔。模板總是至少需要乙個引數,通過args...解包可以遞迴呼叫processvalues(),這樣每次呼叫都會至少用到乙個模板引數。對於遞迴來說,需要終止條件,當解包後的引數只有乙個時,呼叫接收乙個引數模板的processvalues()函式,從而終止整個遞迴。

假如對processvalues()進行如下呼叫:

processsvalues(1, 2.5, "test");

其產生的遞迴呼叫如下:

processsvalues(1, 2.5, "

test");

handlevalue(1);

processsvalues(

2.5, "

test");

handlevalue(

2.5);

processsvalues(

"test");

handlevalue(

"test

");

#include #include

#include

#include

using

namespace

std;

//用來終止遞迴並處理包中最後乙個元素

template void

print(t t)

//包中除了最後乙個元素之外的其他元素都會呼叫這個版本的print

template void

print(t t, types ...arg)

//測試

intmain()

類模板的全特化:就是模板中的引數型別都確定了

類模板的偏特化:就是模板中有些引數確定了,有些沒有確定

注意:模板的全特化和偏特化都要在類模板的基礎上實現

//

先定義類模板

templateclass

test

private

: t1 a;

t2 b;

};//

模板的全特化

template<>

class test

private

:

inta;

char

b; };

//模板的偏特化

template class test

private

:

char

a; t2 b;

};intmain()

可變參模板模板模板引數

include include include include include include include include using namespace std namespace nmsp1 classa template typename.args class myclasst 主模板 t...

C 可變參模板

可變引數模板是乙個接受可變數目引數的模板函式或模板類,在模板引數列表中,typename 指出接下來的引數表示0個或多個型別的列表,乙個型別名後面跟省略號表示0個或多個給定型別的非型別引數的列表。在函式引數列表中,如果乙個引數的型別是乙個模板引數包,則此引數也是乙個函式引數包。可變引數模板通常是遞迴...

可變參模板續 模板模板引數

include include include include include using namespace std 從類模板引入 template t u叫模板引數,更具體叫型別模板引數 前面有typename template typename t,型別模板引數 template class ...