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***类型的函数,由于实参形参类型一致,所以能够直接调用构造函数,构造新链表。构造完后,就执行尾插。

总结:
相关推荐
Frank学习路上1 小时前
【C++】面试:内存管理
c++·面试
hoiii1871 小时前
17自由度铁道车辆横向动力学MATLAB程序
开发语言·matlab
Irissgwe1 小时前
数据结构-二叉树
数据结构·c++·二叉树·c·
大蚂蚁2号1 小时前
Python 项目架构深度解析:从混乱到清晰
开发语言·python·架构
yaoxin52112310 小时前
434. Java 日期时间 API - Period 基于日期的时间段
java·开发语言·python
凡人叶枫10 小时前
Effective C++ 条款30:透彻了解 inlining 的里里外外
linux·开发语言·c++·嵌入式开发·effective c++
noipp10 小时前
推荐题目:洛谷 P10907 [蓝桥杯 2024 国 B] 蚂蚁开会
c语言·c++·算法·编程·洛谷
学逆向的10 小时前
C++纯虚函数
开发语言·c++·网络安全
程序员二叉11 小时前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc