4.7可变参模板

可变参模板的例子

#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)总结
*	获取参数包里面的参数方式有很多种,但是一般来讲都离不开递归这种手段。
*	
*
*
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值