vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考

(1)在阅读vs2019上的 STL库的 map 源码时,遇到了这个函数,之前,在别的源码中也经常出现这个函数。那么这个函数起什么作用呢?
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第1张图片
在1880行,有对该函数的调用。其定义如下图:,青色箭头所指。
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第2张图片
(2)该函数的形参是两个引用。在函数_Move_assign 中,实参是对两个分配器的引用,咱们c++ 里,STL 提供了一个标准分配器,就是allocator模板类。这两个引用都是对allocator对象的引用。
(3)allocator模板类的定义如下图,这里对模板类中一些不重要的函数修饰符去掉了,以突出重点,方便阅读。
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第3张图片
如图所示,allocator模板,定义了默认的空的copy构造和copy赋值运算符函数。没有定义移动构造和移动赋值运算符函数。根据 c++ 语法。会代替调用其copy赋值运算符函数。但该函数为空。所以什么也不做。所以在 _Pocma 函数里,没有执行任何修改数据的代码。换句话说,有没有这行代码都一样。
(4)为了验证上面的想法,咱们修改一下电脑vs2019携带的源文件。即修改allocator模板类,如下,在copy赋值运算符函数里打印:
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第4张图片

这里直接修改了 源文件。实验一下
(5)来一个实验代码如下:
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第5张图片
图中的输出 “yes” 是怎么来的呢,就是因为修改了allocator模板源代码引起的。这非常神奇,也验证了咱们一丝不苟的治学精神,和融会贯通的学习方法,和我们王建伟老师的伟大教学功绩。王老师教的好,才有咱们学的好。
(6)实际上,一开始我不明白这些,是通过反汇编调试看汇编代码时,发现其执行代码没有有效的指令行。才写这篇文章,并回忆起来这个对象复制,对象移动的知识的。谢谢阅读
(7)接着,我们来分析类似的函数 _Swap_adl (…),该函数也经常出现在STL库源码中。如下图
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第6张图片
在STL库 源码中,有map对象的交换函数。其中引用了 _Swap_adl (…) 函数。其两个实参是默认的 map类型的排序函数,也是STD标准库函数。如下图(按升序排序的 less 结构体):
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第7张图片
less 只有默认的构造、析构、copy构造、copy赋值运算符函数。对其移动构造、移动赋值运算符的函数调用转为copy系列的调用。
_Swap_adl 的定义如下图:
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第8张图片
结合到less 的源代码,可见经swap_adl 调用了less 的移动构造和移动赋值运算符函数。可见 swap_adl 在这时候并没有执行什么有用的功能。
我们也可以结合反汇编看一下:
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第9张图片
可见源码中对swap_adl 的调用就是应付,并没有产生实际有意义的代码。STD::move(…) 的返回值储存在rax 寄存器里,这个rax 的返回值没有再传给任何变量。所以对 STD::move(…) 的调用执行了个寂寞。调不调用一样。但实参变化时肯定不是这个结果。但是这样才符合 要求的语义,正确的进行对象交换。
(8)一样搞实验,我们可以修改下 less 源码。
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第10张图片
vs2019 ,c++的STD库全局函数 _Pocma 与 _Swap_adl 的思考_第11张图片
但是实验,并没有取得预期的效果。因为对swap的汇编代码,没有任何变化,还是上面那个图。但咱们继续。。。。。
实验了一下,对less的修改,并不影响 _Swap_adl 的汇编代码。打印结果也出不来。但咱们的对函数里概念的理解是正确的。先这样啦。以后再实验 _Swap_adl 这个函数。

你可能感兴趣的:(c++容器类模板的相关源码分析,c++学习总结,c++,开发语言)