可变参类模板
通过递归组合方式展开参数包
组合关系(复合关系):
class B{
public:
//...
}
class A{
public:
//...
B b, //A中包含B对象
}
组合关系展开参数包案例
template <typename First, typename... Others>
class myclass<First, Others...>{
public:
myclass():m_i(0)
{
printf("s%执行了", this);
}
myclass(First parf, Others... paro):m_i(parf), m_obj(paro ...)
{
printf("s%执行了", this);
}
First m_i;
myclass m_obj; //组合关系,参数多的类包含参数少的类
}
myclass<int, float, double>(12, 13.5f, 23);
注意每一个对象地址都不相同
通过tuple和递归调用展开参数包
实现思路:计数器从0开始,每处理一个参数,计数器+1;
一直到把所有参数处理完, 最后一个模板偏特化,作为处理结束。
元组介绍:
tuple<float,int,int> mytuple(13.4f, 52, 10); //一个元组,一堆东西的组合
cout << get<0>(mytuple) << endl;
cout << get<1>(mytuple) << endl;
cout << get<2>(mytuple) << endl;
通过tuple和递归调用展开参数包案例
//mycount 用于统计,从0开始,mymaxcount表示参数数量
template<int mycount , int mymaxcount, typename...T>
class myclass
{
public:
static void myfunc(const tuple<T...>&t)
{
cout << "value" << get<mycount>(t)< < endl;
myclass<mycount + 1, mymaxcount, T...>::myfunc(t); //递归调用
}
}
//需要一个特殊版本结束递归调用
template<int mymaxcount, typename...T>
class myclass<mymaxcount, mymaxcount, T...>
{
public:
static void myfunc(const tuple<T...>&t)
{
}
}
template<typename...T>
void testfunc(const tuple<T...>&t) //可变参数模板
{
myclass<0, sizeof...(T), T...>::myfunc(t);
}
void func(){
tuple<float,int,int> mytuple(13.4f, 52, 10);
testfunc(mytuple);
}
总结
获取参数包的方法有很多种,一般都离不开递归
模板 模板参数
表示这是个 模板参数,这个模板参数本身,又是 一个模板
template<
typename T; //类型 模板参数
typelate<class> class Container; //模板 模板参数
//或者写成typelate<typename W> typename Container W只是占位,没有用途,可以省略
>
/*
typelate<class>
class Container
*/
class myclass{
T m_i;
Container<T> myc; //Container是作为一个类模板来使用的
//因为它后面带有<T>,所以是类模板。
myclass(){
for(int i = 0; i < 10, ++i){
myc.pushback(i); //如果传入的容器不支持pushback会报错
}
}
};
template<typename T> using MyVec = vector<T, allocator<T>>; //这种套路或者写法很固定
template<typename T> using MyList = list<T, allocator<T>>; //这种套路或者写法很固定
myclass<int, MyVec> myvec_obj; //往容器中塞元素,元素为int