C++學習筆記----可變引數模板
阿新 • • 發佈:2021-01-29
技術標籤: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();