
std::forward_list是 C11 引入的单向链表容器定义在forward_list中。它和std::list很像但每个节点只保存一个指向下一个节点的指针因此更省内存但只能单向遍历。1. 核心特点底层结构单向链表每个节点包含一个next指针和元素值。访问方式只支持前向迭代器只能不能--也不能随机访问。没有size()标准库的std::forward_list不提供size()成员函数。如果需要元素个数只能用std::distance(begin(), end())复杂度 O(n)。插入删除在已知位置之后插入/删除是 O(1)。提供insert_after、emplace_after、erase_after没有普通的insert/erase。头部操作支持push_front、pop_front、emplace_front但没有push_back、pop_back、back()。迭代器失效插入不会使任何迭代器失效erase_after只使被删除元素的迭代器失效。内存开销每个元素一个指针比std::list少一个指针但仍比std::vector大。缓存友好性节点分散遍历通常比vector慢。2. 常用操作cpp#include forward_list std::forward_listint fl {1, 2, 3}; fl.push_front(0); // 头部插入 fl.pop_front(); // 删除头部 fl.emplace_front(10); // 头部直接构造 fl.insert_after(it, 5); // 在 it 之后插入返回新元素迭代器 fl.emplace_after(it, 6); // 在 it 之后直接构造 fl.erase_after(it); // 删除 it 之后的元素返回下一个迭代器 fl.before_begin(); // 第一个元素之前的“虚拟位置” fl.front(); // 第一个元素 fl.empty(); // 是否为空 fl.clear(); // 清空 fl.sort(); // 成员函数稳定排序O(n log n) fl.reverse(); // 反转 fl.unique(); // 删除连续重复元素通常先 sort fl.remove(3); // 删除所有等于 3 的元素 fl.remove_if(pred); // 删除满足谓词的元素 fl.merge(other); // 合并两个有序 forward_list源变空 fl.splice_after(pos, other); // 把 other 的节点移动到 *this不拷贝元素注意std::sort不能用于std::forward_list因为它需要随机访问迭代器。必须用成员函数fl.sort()。3. 与std::list/std::vector的简单对比特性std::forward_liststd::liststd::vector结构单向链表双向链表连续动态数组遍历方向只能向前双向随机访问随机访问不支持不支持支持 O(1)size()无有O(1)有O(1)中间插入删除已知位置后 O(1)已知位置 O(1)O(n)迭代器失效插入不失效删除只失效被删插入不失效删除只失效被删插入可能全部失效每元素额外开销1 个指针2 个指针通常较小可能有预留容量缓存友好差差好适用场景单向遍历、省内存、频繁头部/已知位置后操作需要双向遍历、频繁中间操作频繁随机访问、尾部操作、遍历大多数情况下std::vector仍是默认选择。只有当确实需要频繁在已知位置后插入删除并且不需要双向遍历时std::forward_list才更有优势。#include iostream #include forward_list #include string #include algorithm #include iterator int main() { // 1. 基本操作 std::forward_liststd::string tasks {write, test, deploy}; tasks.push_front(plan); // plan write test deploy // 在 test 前插入 code需要找到 test 的前驱 auto prev tasks.before_begin(); auto it tasks.begin(); while (it ! tasks.end() *it ! test) { prev it; it; } if (it ! tasks.end()) { tasks.insert_after(prev, code); // plan write code test deploy } std::cout tasks: ; for (const auto t : tasks) { std::cout t ; } std::cout \n; // 删除 deploy需要找到它的前驱 prev tasks.before_begin(); it tasks.begin(); while (it ! tasks.end() *it ! deploy) { prev it; it; } if (it ! tasks.end()) { tasks.erase_after(prev); // 删除 deploy } std::cout after erase: ; for (const auto t : tasks) { std::cout t ; } std::cout \n; tasks.remove(test); // 删除所有 test std::cout after remove: ; for (const auto t : tasks) { std::cout t ; } std::cout \n; // 2. 排序、去重、反转 std::forward_listint nums {3, 1, 2, 2, 5, 4}; nums.sort(); // forward_list 成员函数稳定排序 nums.unique(); // 删除连续重复元素 nums.reverse(); // 反转 std::cout nums: ; for (int n : nums) { std::cout n ; } std::cout \n; // 3. splice_after把 b 的节点移动到 a 中不拷贝元素 std::forward_listint a {1, 2, 3}; std::forward_listint b {10, 20, 30}; auto pos a.begin(); // 指向 1 a.splice_after(pos, b); // 把 b 全部插入到 pos 之后1 10 20 30 2 3 std::cout a: ; for (int n : a) { std::cout n ; } std::cout \n; std::cout b empty: std::boolalpha b.empty() \n; // 注意forward_list 没有 size() std::cout a size std::distance(a.begin(), a.end()) \n; return 0; }