概述
相比 vector 和 string,list 的实现更为复杂。它没有重载运算符 [] 接口,底层结构决定了随机访问效率低,因此主要依赖迭代器。同时,list 也没有 reserve 扩容接口,因为它是非连续内存,每次插入一个节点即可。
list 增加了一些特有接口,例如:
sort():底层使用归并排序(注意:STL 算法库中的 sort 不支持 list 的随机访问迭代器,所以需自行实现)。数据量大时,自定义 sort 比调用算法库再复制回 list 更快。merge():归并两个有序列表。unique():去重(要求有序)。remove()/remove_if():删除指定值或满足条件的元素,与 erase 不同,erase 是删除迭代器指向位置。splice():接合,将一个 list 的数据移动到另一个 list 中。
关于迭代器,vector 和 string 使用原生指针作为迭代器,因为底层是连续数组。而 list 的节点不连续,必须对迭代器进行包装,通过运算符重载来实现解引用和自增功能。
底层结构与节点
list 的底层采用带头双向链表。验证 SGI 库源码可知,list 成员变量只有一个 node 指针,构造函数构造出一个头尾相连的哨兵位节点。
节点设计
节点包含三个部分:数据、前驱指针 (prev)、后继指针 (next)。为了简化访问权限控制,这里使用 struct 而非 class,默认成员为 public,避免频繁使用友元函数。

命名规范尽量与标准库保持一致,便于后续 typedef 复用。
迭代器设计
对于不能直接使用原生指针的容器,需要封装迭代器类。通常用 struct 包装,利用其公有特性减少访问限制。
迭代器分类与实现
迭代器的核心功能是 * 解引用获取数据,++ 移动位置。普通迭代器和 const 迭代器区别在于返回值的类型(是否允许修改)。
为了避免代码冗余,可以使用模板参数区分返回值类型,而不是分别封装两个类。
注意:迭代器不需要析构函数,它只是借用节点指针进行访问,销毁工作由 list 管理。

核心接口实现
生命周期管理
构造函数
无参构造创建一个只有哨兵位的双向链表,可抽取为 empty_init 辅助函数复用。
析构函数
复用 clear 清除所有数据节点,最后释放哨兵位。





