int main()
{
string s1 = "biz", s2,
string cc = rcatenate(s1, s2, s3);
cout << "reverse concated = " << cc << endl;
}
These are new to C++11, and are kind of cool.
They allow an additional level of generalisation by replacing the keyword typename with typename… representing the use of a parameter pack of varying size.
template <typename T, typename… Args>
void fun(const T &t, const Args&… rest);
Args is a template parameter pack, and rest a function parameter pack.
int i=0, double d=3.14, string s= "red fish";
fun(i, s, 100, d); // three pack parameters.
fun(s, 100, "Hello"); // two pack parameters.
fun(d, s); // one pack parameter.
fun("Hello again"); // empty pack.
How does the pack sizing work?
Remember than fun had a first parameter const
T &t, and it’s populated by the first argument.
It should be apparent that dealing with variadic templates could be problematic, because we need to handle a variable number of types. To manage the variable number of types we often use recursive functions.
We will look at an example
Here prints one element off the pack at a time. Firstly the standard print …
template<typename T>
ostream &print(ostream &os, const T &t)
{
return os << t << ".\n";
}
… then the variadic one.
template<typename T, typename… Args>
ostream &print(ostream &os, const T &t, const Args&… rest)
{
os << t << ", ";
return print(os, rest…);
}
int main()
{
print(cout, "a", 3);
}