Variadic Templates
基础知识
1 可变参数包,可以很方便的完成recursive function call(递归函数调用)
2 typename... Types || const Types&... args || print(args...) 三个点的位置是语法规定,不必深究
3 const Types&... args 整体表示可以传进去任意类型的任意参数,表示一个pack(包)
4 sizeof...(args)计算pack中参数的数量
5 ...就是一个所谓的pack(包)
用于template parameters,就是template parameters pack(模板参数包)
用于function parameter types,就是function parameter types pack(函数参数类型包)
用于function parameters,就是function parameters pack(函数参数包)
递归函数
//没有这个函数,编译出错
void print()
{// 边界条件,当args为0个时调用
cout << endl;
}
//typename... Types || const Types&... args || print(args...) 三个点的位置是语法规定,不必深究
template < typename T, typename... Types/*模板参数包*/>
//... args 表示可以传进去任意多个参数
//Types表示类型,为模板,typename... Types表示类型可以是任意类型
//const Types&... args 整体表示可以传进去任意类型的任意参数,表示一个pack(包)
void print(const T& firstArg, const Types&... args/*函数参数包*/)
{
//Inside variadic templates,sizeof...(args) yields tje number of arguments
//sizeof...(args)计算pack中参数的数量
//cout << sizeof...(args) << ",";
//打印第一个参数
cout << firstArg << ' ';
//递归调用剩下参数,args...表示包
print(args.../*函数参数包*/);
}
/*
void print(const T& firstArg, const Types&... args) 与 void print(const Types&... args) 可以共存,可以编译通过。
但前者比较特化,后者比较泛化,共存时永远不会调用后者。
*/
template <typename... Types>
void print(const Types&... args) {
}
int main()
{
//第一次调用firstArg为7.5,args为 "hello", bitset<16>(377), 42
//第二次调用firstArg为hello,args为bitset<16>(377), 42
//第三次调用firstArg为bitset<16>(377),args为42
//第四次调用firstArg为42,args为空
//第五次调用参数列表为空,调用重载函数,打印换行
print(7.5, "hello", bitset<16>(377), 42); // print "7.5 hello 0000000101111001 42"
std::cout << "Hello World!
";
}
递归继承
template <typename... Values> class tuple;
template <> class tuple<> { };
//private tuple <Tail...> 完成递归继承
template <typename Head, typename... Tail>
class tuple<Head, Tail...> : private tuple <Tail...> {
typedef tuple<Tail...> inherited;
public:
tuple() { }
tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) { } // 调用base ctor
...
protected:
Head m_head;
};