这2个东西叠加不起来,因为我这的参数个数要可变,类型也要可变。所以C++搞出这个,把这两个叫做参数包。

底层会弄一个数组把这些参数存起来,去取这个数组的值。

这也类似模版的模版,传左值,左值引用,传右值右值引用。

这是运行时的,而刚才的逻辑是编译时的,

如果把0个参数的注释掉那么就报错   不是在运行时候运行到这,是编译时候。三个参数剩两个参数参数包匹配解析这个showlist,以及 0个时候都是编译逻辑。所以结束条件必须用 0个参数做编译条件。

但是实践当中不是这样的,因为这块逻辑没法写,三个参数调用三个参数的,让他实例化生成,我用你实例化生成时候,你里面逻辑是怎么解析参数包内容的,现在在想一想为什么不能按循环去屑。如果我按循环去写的话,我用你这个可变参数模版生成这个模版,这个模版 的内容是什么,

你这个arg是啥,咋取,我是不是要写一个循环,要把这些数据存到一个容器里去,我这写循环肯定是遍历容器

该咋办呢,但是当时容器里面不能存不同类型,当然有办法,但是编译器设计时候没走这个方向。他选择层层解析这个参数。

编译时候的实践过程就变成了这样:

我去调用printf我哦知道你是三个参数 int string double。参数包我就变成这个,参数变成int string double,showlist就变成这样,按照语法逻辑showlkist又回去掉三个参数的,只是语法逻辑上,只推出x,还剩个参数包,y z继续往下传再调用自己,生成两个参数的,。。。在生成一个函数。0个参数有匹配的就不用生成了。

这是编译时递归包扩展,生成不同函数,本质是函数重载,编译调自己实际实例化出的不是调自己的。编译时候使用自己推这个的

cout并不是在一个函数cout 的,是在多个重载函数里面对应解析参数的

无论多少种,我的模版都支持,我的模版是写给编译器的,

调用三次getarg,利用getarg返回值作为实参,之前是编译器递归推演,现在不是递归推演,利用getarg就把每个参数解析出来了

也可以这样。

解析参数包:1.编译时递归

2.多次调用GetArg

上面要插入可变模版参数,,下面要插入值

pushback:如果传的左值,就调用左值版本,

左值就调用拷贝构造

emplace——back也是拷贝构造,可变模版参数,编译器实例化只有一个参数的参数包,T是bitstring,T也被推成左值,折叠就是左值引用,传下去还是左值,所以没区别

考点:pushback,emplaceback 区别

传右值,pushback就走移动构造了,emplace我也调用移动构造

pushback string string传给string,emplace back 是可变参数模版,无论左值右值也是string,实例化出的emplace函数还是string作为形参的。

下面的 推出是string 所以构造,移动构造。

上面推const char* 没有构造直接往下传

推出这个data是个const char*,这个——data类型确定了是T是string  直接诶构造了。他们两个效率差不多,

可以认为这有一个pushback 这有好多个emplace back,2个,只要你传的参数最终能构造下面的pair。或者下面类型支持你两个参数或者几个参数

实践当中不一定需要包的扩展,使用了才需要。

,这个万能引用不好,因为不确定类型,就不能隐式类型转换了。

这也不好,都是一个参数,冲突,没有参数 不冲突。

insert也和pushback一样,不能这么写不确定是pair不能隐式类型转换

还是这样写

此时构造。申请节点时候构造。效率就高

这是构造了个临时对象

pair往下传,这时候调用pair的移动构造

pair的移动构造调用了string移动构造,pair自己也有移动构造,他自己不是深拷贝,但是里面string是深拷贝,

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐