c++oding="utf-8" ?>
必须用 empty() 判空,因 size() 在 libstdc++ 中多为 o(n) 遍历实现,嵌入式裁剪版可能未定义;insert_after() 和 erase_after() 参数是前驱迭代器;splice_after() 是唯一真正 o(1) 拼接操作。

别用 size() 判空,也别在循环里调它——empty() 是唯一可移植、O(1)、不崩溃的空判断方式;insert_after() 和 erase_after() 的参数永远是前驱迭代器,不是目标节点;splice_after() 是唯一真正 O(1) 的拼接操作,其他方式都会毁掉内存与性能优势。
为什么 fl.size() == 0 必须替换成 fl.empty()
size() 在 libstdc++(GCC 默认 STL)多数版本中仍是 O(n) 遍历实现,调用一次等于遍历整个链表;某些嵌入式裁剪版甚至未定义该函数,直接调用会编译失败或返回垃圾值。更隐蔽的风险是:在循环条件中写 for (size_t i = 0; i ,会让本应 O(n) 的遍历退化成 O(n²)。
- 判空必须用
fl.empty()—— 它始终 O(1),且 guaranteed defined - 若需长度且只用一次:
auto len = std::distance(fl.begin(), fl.end());,结果存局部变量复用 - 若长度需高频访问(如 LRU 缓存计数器):手动维护一个
size_t m_size,每次push_front()、insert_after()、erase_after()后同步增减 - 禁止封装类里偷偷加
__size()等非标扩展——MSVC 可能有,libstdc++ 没,不可移植
insert_after() 和 erase_after() 的参数到底指谁
这两个函数的操作对象永远是「参数迭代器所指节点的下一个节点」,不是参数本身。这是单向链表无法回溯的硬约束,不是 API 设计疏漏。传错迭代器(比如 fl.begin() 或 fl.end())会删错位置、跳过节点,甚至触发未定义行为。
- 头插唯一安全写法:
fl.insert_after(fl.before_begin(), x),或更简洁的fl.push_front(x) - 删首节点必须用:
fl.erase_after(fl.before_begin()),等价于fl.pop_front();传fl.begin()实际删的是第二个元素 - 删第 n 个元素(n ≥ 1):
auto prev = std::next(fl.before_begin(), n - 1); fl.erase_after(prev);—— 注意是n - 1,不是n - 遍历时删当前匹配节点:初始化
auto prev = fl.before_begin(),循环内用auto curr = std::next(prev)定位,匹配后执行prev = fl.erase_after(prev)(它返回被删节点之后的有效迭代器) - 绝对禁止传
fl.end()给任一函数 —— 未定义行为,GCC/Clang 可能静默崩溃,MSVC 可能触发断言
什么时候必须用 splice_after() 而不是循环插入
splice_after() 是 std::forward_list 唯一真正 O(1) 的物理拼接操作:不调用构造/析构、不分配内存、不拷贝数据,只改 next 指针。任何用 insert_after() 循环插入、或先 push_front() 再反转的做法,都会让内存和性能优势彻底归零。
- 整体迁移:
dst.splice_after(pos, src),拼接后src变为空容器 - 单节点迁移:
dst.splice_after(pos, src, it),把src中it所指节点移到dst - 范围迁移:
dst.splice_after(pos, src, first, last)(左闭右开),仅拼接[first, last) -
src和dst必须同类型且不能是同一对象 —— 自拼接(fl.splice_after(pos, fl))是未定义行为 - 典型场景:LRU 缓存中把命中节点提到头部 →
fl.splice_after(fl.before_begin(), fl, it)
真正省内存只发生在「节点多 + 值类型小」时(64 位系统下每个节点省 8 字节),而所有优势都依赖你避开 size()、严守前驱逻辑、只在必要时用 splice_after() —— 这三个点一旦出错,就不是慢一点的问题,而是直接失去使用 std::forward_list 的全部意义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











