可变参模板的例子
#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>
using namespace std;
//可变参函数的简单例子
/*
* 1.我么一般吧args称为一包或者一堆参数,而且这些参数类型是可以不同的。
* 2.我们理解T这种类型,不要理解为一个类型,而是0到多个类型。
* 3.一包参数中可以容纳0到多个模板参数,而且这些模板参数可以是任意类型。
* 4.注意:
* T... 可变参类型,是一包类型
* args可变形参,一包形参
*5.&的位置出现在类型名后面
*/
template<typename ... T>
void myFunction(T...args)
{
cout << "args=" <<sizeof...(args) << endl;
cout << sizeof...(T) << endl;
}
//例子2
template<typename T,typename ...U>
void myFunction02(const T&firstarg,const U&...otherargs)
{
cout << sizeof...(otherargs) << endl;//sizeof...可变参的数量
}
void func()
{
myFunction();
myFunction(10, 20);
myFunction(10, 20,23,4343.34);
cout << "----------------------------------" << endl;
myFunction02(1, 23, 43);//2,至少有一个参数
}
int main(void)
{
func();
system("pause");
return 0;
}
/*
*(1)可变参函数模板 variadic templates
*允许模板中包含0个到任意个模板参数,在语法上和传统的模板不一样,使用 ...
*
*
*(3)
*
*
*/
可变参函数模板参数包的展开_一个参数加一包函数容易解包
#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>
using namespace std;
//递归终止函数
void myFunction02()
{
cout << "参数解包完成,这是终止函数" << endl;
}
//例子2
template<typename T, typename ...U>
void myFunction02(const T&firstarg, const U&...otherargs)
{
cout << sizeof...(otherargs) << endl;//sizeof...可变参的数量
//注意下面的递归调用展开,,把一包东西分为1+1包,直到最后为1+0
cout << "第一个参数的值为:" << firstarg << endl;
myFunction02(otherargs...);//当只有一个参数的时候,需要进行递归中值函数
}
void func()
{
myFunction02(1, 23, 43);//2,至少有一个参数
}
int main(void){
func();
system("pause");
return 0;
}
/*
*(2)可变参函数模板参数包的展开_一个参数加一包函数容易解包
*展开的套路比较固定,一般都是使用递归函数的方式来展开:c
*要求我们在代码编写过程中有一个参数包展开函数和递归终止条件。
* 一个参数+一包参数,最合适参数包的展开。
void myFunction02(const T&firstarg,const U&...otherargs)
*
*
*(3)
*
*
*/
可变参类模板_通过继承递归展开调用
#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>
using namespace std;
//1.使用递归继承方式展开参数包
template<typename ...Args>class myclass{};//主模板
//手写一个参数为0的特化版本
template<>class myclass<>//0个模板参数特化版本
{
public:
myclass()
{
cout << "0个模板参数特化版本执行"<<this << endl;
}
};
template<typename First,typename ...Other>
class myclass<First,Other...>:private myclass<Other...>
{
public:
myclass():m_i(0)
{
cout << "myclass的构造函数执行了"<<this << endl;
}
//有参构造函数
myclass(First parf,Other...Paro):m_i(parf),myclass<Other...>(Paro...)//调用父类的构造函数
{
cout << "有参数构造函数执行"<<this << endl;
}
public:
First m_i;
};
int main(void)
{
myclass<int, float, double>myc;
/*
* 执行三次构造函数
* myclass<int,float,double>--->myclass<int ,float>--->myclass<int>
*
* 0个模板参数特化版本执行0020F73C
myclass的构造函数执行了0020F73C
myclass的构造函数执行了0020F73C
myclass的构造函数执行了0020F73C
*/
cout << "----------------" << endl;
myclass<int,float,double> my_class01(12, 123.565, 344.5845734958);
/*
* 0个模板参数特化版本执行0039F74C
有参数构造函数执行0039F74C
有参数构造函数执行0039F74C
有参数构造函数执行0039F74C
*/
system("pause");
return 0;
}
/*
*(1)可变参类模板
*允许模板中定义0个到任意个模板参数,这是中高级话题,使用不多。
* 1.使用递归继承方式展开参数包
每次子类都分成1+包,最后为0,进行递归调用.
注意递归继承
*
*
*(2)在命令提示符里面使用dumbin /all 文件名字 >mytext.txt
*查看有多少类生成。
*
*
*
*/
可变参类模板_通过递归组合方式展开函数包
#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>
using namespace std;
//1.使用递归组合方式方式展开参数包
template<typename ...Args>class myclass {};//主模板
//手写一个参数为0的特化版本
template<>class myclass<>//0个模板参数特化版本
{
public:
myclass()
{
cout << "0个模板参数特化版本执行" << this << endl;
}
};
template<typename First, typename ...Other>
class myclass<First, Other...> //:private myclass<Other...>
{
public:
myclass() :m_i(0)
{
cout << "myclass的构造函数执行了" << this << endl;
}
//有参构造函数
myclass(First parf, Other...Paro) :m_i(parf),m_o(Paro...)//, myclass<Other...>(Paro...)//调用父类的构造函数
{
cout << "有参数构造函数执行" << this << endl;
}
public:
First m_i;
//组合关系
myclass<Other...>m_o;//参数多的类包含着参数少的类
};
int main(void)
{
myclass<int, float, double> myclass01(1, 23.32, 34.545);
/*
* 0个模板参数特化版本执行0041FA94
有参数构造函数执行0041FA8C
有参数构造函数执行0041FA84
有参数构造函数执行0041FA7C
组合关系对象首地址都不一样
*/
system("pause");
return 0;
}
/*
*(1)通过递归组合方式展开函数包
*
*(2)
*
*(3)
*
*
*/
可变参类模板_通过tuple和递归调用展开函数包
#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>
#include<queue>
#include<functional>
using namespace std;
//mycount用于统计,myMaxCount表示参数数量
template<int mycount,int myMaxCount,typename ...T>
class myclass
{
public:
static void myFunction02(const tuple<T...>&t)
{
cout << "value="<<get<mycount>(t) << endl;
myclass<mycount + 1, myMaxCount, T...>::myFunction02(t);
}
};
//特化版本用于结束调用
template<int myMaxCount,typename ...T>
class myclass<myMaxCount,myMaxCount,T...>
{
public:
static void myFunction02(const tuple<T...>&t)
{
;
}
};
template<typename ...T>
void myFunction(const tuple<T...>&t)//可变参函数模板
{
myclass<0, sizeof...(T), T...>::myFunction02(t);
}
int main(void)
{
//元组示意
tuple<float, int, int>mytuple(12.34f, 100, 1);
cout << get<0>(mytuple) << endl;
cout << get<1>(mytuple) << endl;
myFunction(mytuple);
system("pause");
return 0;
}
/*
*(1)通过tuple和递归调用展开函数包--需要些类的特化版本,有一定的难度。
*有一个从0开始的计数器,每次处理一个参数,计数器+1,一直到所有参数处理完毕。
*最后使用使用一个模板偏特化,作为递归调用结束。
*
*(2)
12.34
100
value=12.34
value=100
value=1
*
*(3)总结
* 获取参数包里面的参数方式有很多种,但是一般来讲都离不开递归这种手段。
*
*
*
*/