C++可变参数模板
1.可变参数模板的格式
如上,args可以传0到多个参数,可以传不同类型的参数
注意下面的两个概念:
Args是模板参数包,args是一个函数形参参数包
这里面的args可以传入不同的类型,通过sizeof(args)可以求出参数个数
但是这样写是运行不了的,因为可变参数模板要求展开使用:
2.展开参数包
递归展开参数包
逗号表达式展开参数包
如上图,这种展开方式不需要通过递归中值函数,而是直接在expand函数体中展开,printArg不是递归中值函数,只是一个处理参数包中每一个参数的函数。
这种展开方式实现的关键是逗号表达式,它是按顺序执行逗号前面的表达式。先执行printArgs,再得到表达式结果0.
而且这里用到了初始化列表,他会展开成{(printArgs(arg1),0),(printArgs(arg2),0),(printArgs(arg3),0),(printArgs(arg4),0)...}。
其实不一定非得是0,只要是整型就行,主要就是为了有一个逗号表达式的返回值。
所以其实上面的展开还可以这样去写:
3.stl相关函数
我们就以emplace_back为例进行讲解
可以看出,emplace_back是可变参数模板,所以说,当传入的是右值,就会使用右值引用的形式,当传入的是左值,那就和push_back没有区别
如上图,前两个用法是一样的,但是后两个就不一样了,emplack_back是可变参数模板,所以可以接收多个参数,然后会拿着这个参数包层层传递(就好像上面讲的一样,一直传下去),直到最后构造节点那里,才将参数解析成pair中的first和second进行直接构造。
而push_back不接受多参数传递,所以不能使用倒数第三种方式,而只能是传一个对象或者传列表进行类型转换进行直接构造构造出临时对象,然后再进行移动构造(c++11底层都支持移动构造,而且临时对象是个将亡值)将他传给push_back的参数。
所以其实emplace_back和pushback差别不太大,就是在构造对象的时机上有差别。