(1)list源码分析,基于c++ 和vs2019,cpp20标准。结构确实如图,双向环形链表。

++ 经后来分析,上述的结构还可以具体些,自己画了一个:

(2) 关于list类型变量的初始化思考,如下图:

我们可以如此初始化 list 变量并赋值。但实际上 list 并没有如此直接对应的构造函数。实际编译器的做法是,把{9,10,11} 初始化给了initializer_list类型的变量。如下图:

内存中确实有这样的9,10,11 的数据序列,其起始和终止地址作为指针初始化了 initializer_list 变量。然后再以这个initializer_list 变量来作为实参,来初始化 list 变量,调用如下的 list 构造函数:

这些都是咱们猜测的编译器的编译原理。毕竟没看过c++编译器是怎么编译这些代码的。但咱们可以反汇编验证一下:

可见,代码力确实存在对 initializer_list 的使用。确实是这么构造 list 的。 谢谢
(3)数据结构


(4)现在学习容器的删除函数,主要是迭代器的使用:

++ 此 erase ( ) 函数的源码如下:

(5)继续学习迭代器的删除操作,目前的一个结论是,不可以对指向 list . begin()这个首元素进行递减操作:

(6)同理,迭代器的递增操作也不适用于 end()迭代器:

(7)以上讨论,确定了使用 删除 erase()函数的大体的代码框架:

++ 给出源代码版本:
#include <iostream>
#include <list>
using namespace std;
int main() // 本例中编写的 for 的循环条件,也很精妙!!
{ // 本测试的意图是删除链表里所有的 2 ,且 2 既在开头也在链尾
list<int> myList{2,1,2,2,2,3,2,4,2,5,2,2,2,6,7,8,9,2,2,2};
auto iterBegin = myList.begin(), iterEnd = myList.end();
for (auto iter = iterBegin; iter != iterEnd ; ) //省略递增条件
if (*iter == 2)
iter = myList.erase(iter);
else
iter++;
for (auto iter = myList.begin(); iter != iterEnd; iter++)
cout << *iter << " ";
cout << endl;
return 0;
}
(8)
谢谢
文章详细分析了C++中的list容器源码,基于C++20标准和VS2019环境。它指出list实际上是一个双向环形链表,并讨论了list类型的变量初始化过程。编译器将花括号初始化转换为使用initializer_list,先创建数据序列,然后利用这个序列初始化list。通过反汇编验证了这一编译策略。
11万+

被折叠的 条评论
为什么被折叠?



