一、std::list 与 std::forward_list 概述
std::list 和 std::forward_list 都是 C++ STL 中的链表容器,用于存储动态大小的元素集合。
两者的核心区别在于链表结构和遍历方式:
C++ 标准库中 std::list 为双向链表,支持双向遍历及任意位置 O(1) 插入删除,但内存占用较高且不支持随机访问。std::forward_list 为单向链表,内存占用更低,仅支持单向遍历。两者均不支持随机访问,迭代器在删除元素时可能失效。选择依据主要为是否需要双向遍历及内存敏感程度。

std::list 和 std::forward_list 都是 C++ STL 中的链表容器,用于存储动态大小的元素集合。
两者的核心区别在于链表结构和遍历方式:
| 特性 | std::list | std::forward_list |
|---|---|---|
| 链表类型 | 双向链表 | 单向链表 |
| 插入/删除效率 | 任意位置 O(1) | 任意位置 O(1) |
| 随机访问 | 不支持 | 不支持 |
| 内存占用 | 较高(每个节点包含前后指针) | 较低(仅有后继指针) |
| 适用场景 | 需要频繁中间插入/删除 | 内存敏感且仅需单向遍历 |
prev 和 next 指针,支持从前到后或从后到前的遍历。[] 或 at() 访问元素。#include <list>
#include <iostream>
int main() {
// 1. 初始化
std::list<int> l1; // 空 list
std::list<int> l2(5, 100); // 5 个 100: {100, 100, 100, 100, 100}
std::list<int> l3 = {1, 2, 3}; // 列表初始化
// 2. 插入与删除
l1.push_back(4); // 尾部插入
l1.push_front(0); // 头部插入
l1.pop_back(); // 尾部删除
l1.pop_front(); // 头部删除
l1.insert(++l1.begin(), 5); // 插入到指定位置
l1.erase(l1.begin()); // 删除指定位置
// 3. 遍历
for (const auto& val : l1) {
std::cout << val << " ";
}
// 4. 其他操作
l1.sort(); // 排序
l1.reverse(); // 反转
l1.merge(l2); // 合并两个有序链表
l1.unique(); // 去重
return 0;
}
#include <forward_list>
#include <iostream>
int main() {
// 1. 初始化
std::forward_list<int> fl1; // 空链表
std::forward_list<int> fl2(5, 100); // 5 个 100
std::forward_list<int> fl3 = {1, 2, 3}; // 列表初始化
// 2. 插入与删除
fl1.push_front(0); // 头部插入
fl1.pop_front(); // 头部删除
auto it = fl1.before_begin(); // 获取头节点前的位置
fl1.insert_after(it, 5); // 在指定位置后插入
fl1.erase_after(it); // 删除指定位置后的元素
// 3. 遍历
for (const auto& val : fl3) {
std::cout << val << " ";
}
// 4. 其他操作
fl1.sort(); // 排序
fl1.reverse(); // 反转
fl1.merge(fl2); // 合并两个有序链表
fl1.unique(); // 去重
return 0;
}
| 特性 | std::list | std::forward_list |
|---|---|---|
| 链表类型 | 双向链表 | 单向链表 |
| 插入/删除效率 | 任意位置 O(1) | 任意位置 O(1) |
| 随机访问 | 不支持 | 不支持 |
| 内存占用 | 较高 | 较低 |
| 迭代器稳定性 | 插入/删除不影响其他迭代器 | 同上 |
| 适用场景 | 双向遍历、频繁插入删除 | 内存敏感、单向遍历 |
merge()。before_begin() 在头部插入;链表无法通过下标访问元素,应使用迭代器。
std::list<int> l = {1, 2, 3};
auto it = l.begin();
std::advance(it, 2); // 移动到第 3 个元素
std::cout << *it; // 输出 3
删除节点会使指向该节点的迭代器失效,应重新获取。
std::list<int> l = {1, 2, 3};
auto it = l.begin();
++it; // 指向 2
it = l.erase(it); // 删除 2,返回指向 3 的新迭代器
在内存敏感场景中优先使用 std::forward_list。
std::forward_list<int> fl = {1, 2, 3};
std::list<std::string> tasks = {"Task1", "Task2"};
tasks.push_back("Task3");
tasks.insert(++tasks.begin(), "Task1.5");
std::forward_list<int> queue;
queue.push_front(1);
queue.push_front(2);
queue.pop_front(); // 删除头部元素
| 容器 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| std::list | 插入/删除高效,支持双向遍历 | 内存占用高,不支持随机访问 | 频繁中间插入/删除 |
| std::forward_list | 占用低,插入/删除高效 | 仅单向遍历 | 内存敏感、单向操作 |

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online