C++ 可变参数模板深剖

本文介绍了C++11的可变参数模板,包括概念、模板定义、参数包展开和emplace的使用方法及工作原理。通过递归和逗号表达式展开详细解释了参数包的处理,并探讨了emplace接口在STL容器中的应用及其优势。
摘要由CSDN通过智能技术生成

传统艺能😎

小编是双非本科大一菜鸟不赘述,欢迎米娜桑来指点江山哦(QQ:1319365055)

🎉🎉非科班转码社区诚邀您入驻🎉🎉
小伙伴们,打码路上一路向北,彼岸之前皆是疾苦
一个人的单打独斗不如一群人的砥砺前行
这是我和梦想合伙人组建的社区,诚邀各位有志之士的加入!!
社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)
直达: 社区链接点我


在这里插入图片描述

概念🤔

C++11 新增一员猛将就是可变参数模板,他可以允许可变参数的函数模板和类模板来作为参数,使得参数高度泛化

在 C++11 之前类模板和函数模板中只能包含固定数量模板参数,而且也有可变参数的概念,比如 printf 函数就能够接收任意多个参数,但这是函数参数的可变参数,并不是模板的可变参数。可变模板参数无疑是一个巨大的改进,但由于可变参数模板比较抽象,因此使用起来并不会太简单。

模板定义🤔

函数的可变参数模板定义方式如下:

template<class …Args>
返回类型 函数名(Args… args)
{
   
  //函数体
}

比如:

template<class ...Args>
void ShowList(Args... args)
{
   }

注意这里的书写格式,模板参数Args前面有省略号,代表它是一个可变模板参数, 我们把带省略号的参数称为参数包 \color{red} {我们把带省略号的参数称为参数包} 我们把带省略号的参数称为参数包,参数包里面可以包含0到 N(N≥0) 个模板参数, 而 a r g s 则是一个函数形参参数包 \color{red} {而 args 则是一个函数形参参数包} args则是一个函数形参参数包
模板参数包 Args 和函数形参参数包 args 的名字可以任意指定,并不是说必须叫做 Args 和 args 。

那么现在函数传参就可以实不同类型了:

int main()
{
   
	ShowList();
	ShowList(1);
	ShowList(1, 'A');
	ShowList(1, 'A', string("hello"));
	return 0;
}

然后在函数模板中通过sizeof计算参数包中参数的个数:

template<class ...Args>
void ShowList(Args... args)
{
   
	cout << sizeof...(args) << endl; //获取参数包中参数的个数
}

现在最大的难点就是我们无法直接获取参数包中的每个参数语法并不支持使用 args[i] 的方式来获取参数包中的参数,只能通过展开参数包的方式来获取,这是使用可变参数模板的一个主要特点。

template<class ...Args>
void ShowList(Args... args)
{
   
	//错误示例:
	for (int i = 0; i < sizeof...(args); i++)
	{
   
		cout << args[i] << " "; //打印参数包中的每个参数
	}
	cout << endl;
}

参数包展开🤔

递归函开😎

该方法大概分为三步:

  1. 给函数模板增加一个模板参数,从接收的参数包中分离出一个参数出来
  2. 在函数模板中递归调用该函数模板,调用时传入剩下的参数包
  3. 继续递归,直到参数包中所有参数都被取出来

比如:

template<class T, class ...Args>
void ShowList(T value, Args... args)
{
   
	cout << value << " "; //打印分离出的第一个参数
	ShowList(args...);    //继续递归调用
}

那么最后还有一个问题就是:递归展开该如何终止?

方法其实挺简单就是写一个无参的递归终止函数,该函数的函数名与展开函数的函数名相同,如果传入的参数包中参数个数是 0,那么就会匹配到这个无参递归终止函数,这样就结束了递归:

//递归终止函数
void ShowList
评论 88
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔乔家的龙龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值