C++基础知识—可变参数函数模板和类模板

本文详细介绍了C++中的可变参数函数模板和类模板的使用,包括递归展开参数包的方法。通过示例展示了如何利用递归继承和组合来处理可变参数,并利用tuple进行递归调用展开参数包。此外,还提供了可变参数模板在处理元编程和泛型编程中的应用场景。
摘要由CSDN通过智能技术生成

C++基础知识—可变参数函数模板和类模板


一、可变参数函数模板

代码示例:

#include <iostream>
using namespace std;

void myfunct2()
{
	cout << "参数包展开时执行了递归终止函数myfunc2()" << endl;
}

template <typename T, typename...U>
void myfunct2(const T& firstarg, const U&...otherargs)
{
	cout << "收到的参数值为:" << firstarg << endl;
	myfunct2(otherargs...);
}
int main()
{
	myfunct2(10, "abc", 12, 7);
	return 0;
}

输出结果:

收到的参数值为:10
收到的参数值为:abc
收到的参数值为:12
收到的参数值为:7
参数包展开时执行了递归终止函数myfunc2()

二、可变参数类模板

1、递归继承展开参数包

代码示例:

#include <iostream>
using namespace std;

template<typename...Args>
class myclasst
{
public:
	myclasst()
	{
		cout << "myclasst::myclasst()泛化版本执行了,this = " << this << endl;
	}
};

// 也可以用带零个模板参数的泛化的实例化
#if 1
template<>
class myclasst<>
{
public:
	myclasst()
	{
		cout << "myclasst::myclasst()特殊的特化版本执行了,this = " << this << endl;
	}
};
#endif

template<typename First, typename...Others>
class myclasst<First, Others...> :private myclasst<Others...>	//偏特化
{
public:
	myclasst() : m_i(0)
	{
		cout << "myclasst::myclasst()偏特化版本执行了,this = " << this << "sizeof...(Others)=" << sizeof...(Others) << endl;
	}
	myclasst(First parf, Others...paro) :m_i(parf), myclasst<Others...>(paro...)
	{
		cout<<"------------------begin-------------------"<<endl;
		cout<<"myclasst::myclasst(parf,...paro)执行了,this = "<<this<<endl;
		cout<<"m_i = " <<m_i<<endl;
		cout<<"-------------------end--------------------"<<endl<<endl;
	}
	First m_i;
};

int main()
{
	myclasst<int, float, double>myc(12,13.5,23);
	return 0;
}

输出结果:

myclasst::myclasst()特殊的特化版本执行了,this = 0055F9B4
------------------begin-------------------
myclasst::myclasst(parf,...paro)执行了,this = 0055F9B4
m_i = 23
-------------------end--------------------

------------------begin-------------------
myclasst::myclasst(parf,...paro)执行了,this = 0055F9B4
m_i = 13.5
-------------------end--------------------

------------------begin-------------------
myclasst::myclasst(parf,...paro)执行了,this = 0055F9B4
m_i = 12
-------------------end--------------------

2、递归组合展开参数包

代码示例:

#include <iostream>
using namespace std;

template<typename...Args>
class myclasst
{
public:
	myclasst()
	{
		cout << "myclasst::myclasst()泛化版本执行了,this = " << this << endl;
	}
};

// 也可以用带零个模板参数的泛化的实例化
#if 1
template<>
class myclasst<>
{
public:
	myclasst()
	{
		cout << "myclasst::myclasst()特殊的特化版本执行了,this = " << this << endl;
	}
};
#endif

template<typename First, typename...Others>
class myclasst<First, Others...>	/*:private myclasst<Others...>		//偏特化*/
{
public:
	myclasst() : m_i(0)
	{
		cout << "myclasst::myclasst()偏特化版本执行了,this = " << this << "sizeof...(Others)=" << sizeof...(Others) << endl;
	}
	myclasst(First parf, Others...paro) :m_i(parf), m_o(paro...)	/*myclasst<Others...>(paro...)*/
	{
		cout << "------------------begin-------------------" << endl;
		cout << "myclasst::myclasst(parf,...paro)执行了,this = " << this << endl;
		cout << "m_i = " << m_i << endl;
		cout << "-------------------end--------------------" << endl << endl;
	}
	First m_i;
	myclasst<Others...> m_o;
};
int main()
{
	myclasst<int, float, double>myc(12, 13.5, 23);
	return 0;
}

输出结果:

myclasst::myclasst()特殊的特化版本执行了,this = 00DBFAE8
------------------begin-------------------
myclasst::myclasst(parf,...paro)执行了,this = 00DBFAE0
m_i = 23
-------------------end--------------------

------------------begin-------------------
myclasst::myclasst(parf,...paro)执行了,this = 00DBFAD8
m_i = 13.5
-------------------end--------------------

------------------begin-------------------
myclasst::myclasst(parf,...paro)执行了,this = 00DBFAD0
m_i = 12
-------------------end--------------------

3、tuple和递归调用展开参数包

代码示例:

#include <iostream>
#include <tuple>

using namespace std;

// 类模板得泛化版本
template<int mycount, int mymaxcount, typename...T>	//mycount用于统计,从0开始,mymaxcount表示参数数量,可以用sizeof...获得
class myclasst2
{
public:
	static void mysfunc(const tuple<T...>& t)
	{
		cout << "value = " << get<mycount>(t) << endl;	//可以把每个参数取出来并输出
		myclasst2<mycount + 1, mymaxcount, T...>::mysfunc(t); //计算每次+1,这里时递归调用自己;
	}
};

// 偏特化版本,用于结束递归调用
template<int mymaxcount, typename...T>
class myclasst2<mymaxcount, mymaxcount, T...>
{
public:
	static void mysfunc(const tuple<T...>& t)
	{
	}
};

template<typename...T>
void myfunctuple(const tuple<T...>& t)	// 可变参函数模板
{
	myclasst2<0, sizeof...(T), T...>::mysfunc(t);	// 第一个参数为0,从0开始计数;
}
#endif

int main()
{
	tuple <float, int, int>mytuple(12.5f, 100, 52);
	myfunctuple(mytuple);
	return 0;
}

输出结果为:

value = 12.5
value = 100
value = 52

总结

1、可变参函数模板用展开参数包
2、可变参类模板用展开参数包
3、tuple和递归调用展开参数包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值