1. 程式人生 > 其它 >C++學習筆記----可變引數模板

C++學習筆記----可變引數模板

技術標籤:C++

可變引數模板的用法
可變引數模板也就是模板引數數目和型別可變,我們用引數包 來傳遞多個可變的引數。我們用class…和typename…來表示一個引數包,引數包表示零個或者多個引數的列表。

/*
Args 表示一個模板引數包,rest表示一個函式模板引數包
*/
template<typename T,typename... Args>
void fun(const T &t,const Args &...rest);
int i=10;
double d=5.0;
string s(hello);
fun(i,s,49,d);//包中有三個引數s,49,d
fun(s,i,d);包中有兩個引數i,d fun(s);//空包

sizeof…()
sizeof…()函式返回函式引數包或者模板引數包中的引數的數量。

可變引數模板例項
可變引數模板通常是用於遞迴函式的,我們將編寫一個函式依次輸出引數包中的各個資料,我們採用遞迴的方式經輸出,首先定義一個普通的引數模板作為遞迴函式的出口,遞迴出口要定義在可變引數模板的前面。

//遞迴函數出口,需要定義在可變引數模板的前面
template<typename T>
ostream& print(ostream &os,const T &t)
{
    os << t;
return os; } //可變引數模板, template<typename T,typename... Args> ostream& print(ostream &os,const T &t,const Args&... rest) { os << t <<" "<<sizeof...(Args)<<" "<< sizeof...(rest) << endl; return print(os, rest...);
} int main() { string s("this is a test"); int i = 10; print(cout,i,s,42); return 0;

上述引數模板在進行遞迴呼叫時我們僅僅傳入了兩個引數,一個輸出流物件的引用,和一個引數包,因為函式模板中有三個引數,所以rest…引數包中的第一個引數將會匹配到const T &t引數的位置,因此每遞迴呼叫一次引數包中的值就會少一個。直到引數包中只有有一個引數是將會呼叫非可變引數的模板函式,這時函式遞迴結束。
函式遞迴執行如下:
在這裡插入圖片描述可變引數擴充套件
可以對可變引數的包做出擴充套件,其擴充套件操作如下:

template<typename T>
T& debug_rep( T &t) 
{
    return t;
}

template<typename...Args>
ostream& erroMsg(ostream &os,const Args&...rest)
{
    return print(os,debug_rep(rest)...);
}

對之前的例子做出如上的兩個函式模板的宣告。現在我們可以進行如下的操作:

int main()
{
    string s("this is a test");
    int i = 10;
    erroMsg(cout,i,s,42);

    return 0;
}

上述的erroMsg(cout,i,s,42);相當於呼叫
print(cout,debug_rep(i),debug_rep(s),debug_rep(42));
上述案例中的print(os,debug_rep(rest)…)相當於對引數包rest中的每個引數呼叫debug_rep();