c++数据结构之c++11(三)

一.可变参数模板

1.原理

注:引用须遵循引用折叠。用"..."指出一个模板参数或函数参数(Args)来表示一个包,这样在实例化的时候,就可以随意改变形参个数,即有0-N个参数。

可变参数模板就相当于模板的模板,有了它,就可以让编译器自动实现,生成相应参数个数的函数模板,并由这些模板结合指定数据类型,实例化出相应的函数:

2.包扩展

注:sizeof...是个操作符,可用于求可变参数模板实例化以后,参数包里参数的个数:

①.问题引入:

如果想要把实例化以后,参数包里的数据(实参)取出来,很多人想到的是这样的方法:

但这样是不支持的。

此时若要解析出参数包的内容,需要进行包扩展:

②.包扩展

玩了一波递归,让参数包第一个参数传给x,其余参数传给第二个参数包args,然后逐个逐个取参数包首参数:

但这里的递归属于编译时递归包的展开,不属于运行时的递归,运行时的递归自己调用自己,连函数参数的数量,种类都是一致的;而递归包的展开,每一层递归的参数数量是在减少的,且递归包里的参数数据类型并不相同:

3.emplace系列接口

Ⅰ.emplace_back和push_back的对比(以list为例)

Ⅰ-1形参的区别

从两个接口的形参可以看出,push_back插入的是定数量的参数,而emplace_back插入的是参数包。

Ⅰ-2使用的区别
传左值:

结果没有任何区别,emplace_back和push_back一样,先走拷贝构造,将数据用于构造新节点,然后尾插。实参是左值,push_back就去走形参是左值的重载,emplace_back通过引用折叠,实参处整个引用的性质仍旧是左值。

二者运行的结果:

传右值:

结果仍旧相同,只是传右值走的是移动构造而已。

直接传参:
解析过程:

push_back:

链表内节点类型为string,因此push_back被实例化为了string 的push_back。而此时的实参"11111111111111"是个const char* 类型的参数,所以要走一个隐式类型转换, 因此要去调用构造函数,构造一个string类型 的,内容是"11111111111111"的临时变量 。由于临时变量的属性是右值,所以在利用这个临时变量,构造新节点时,走一个移动构造。最后创建好新节点,就执行尾插。

emplace_back:

而emlace_back是根据实参类型来进行实例化的,因为该函数模板是可变参数模板,属于模板的模板,先通过list实例化为函数模板,再由实参"1111111111111" 直接推导出参数类型为const char* ,所以函数模板被实例化为了**const char***类型的函数,由于实参形参类型一致,所以能够直接调用构造函数,构造新链表。构造完后,就执行尾插。

总结:
相关推荐
星栈独行4 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
2601_954526755 小时前
【工业传感与算法实战】温漂补偿与零点抗漂破局:基于二阶多项式拟合的 C/C++ 边缘校准算法,深度拆解“压力变送器什么牌子好”的技术硬指标
c语言·c++·算法
qq_448011165 小时前
C语言中的变量和函数的定义与声明
android·c语言·开发语言
code_pgf5 小时前
`unordered_map` 详解
c++
孫治AllenSun6 小时前
【DataX】生产环境搭建DataX集群案例
java·开发语言·jvm
一拳一个呆瓜7 小时前
【STL】iostream 编程:检测提取操作产生的错误
c++·stl
稚南城才子,乌衣巷风流7 小时前
判断素数与拓展应用
c++
众少成多积小致巨7 小时前
C++ 规范参考(下)
c++
c238567 小时前
把 C++ 内存分配拆透:new 与 malloc 的三层血缘
开发语言·c++·算法
moonsims8 小时前
星闪在跨域无人化系统作用
开发语言·php