C++ STL 编程完全指南
从入门到实践 · 含完整代码示例
2026年5月
目录
[1. STL 概述](#1. STL 概述)
[2. 容器(Containers)](#2. 容器(Containers))
[2.1 顺序容器](#2.1 顺序容器)
[2.2 关联容器](#2.2 关联容器)
[2.3 无序容器](#2.3 无序容器)
[2.4 容器适配器](#2.4 容器适配器)
[3. 迭代器(Iterators)](#3. 迭代器(Iterators))
[3.1 迭代器分类](#3.1 迭代器分类)
[3.2 迭代器操作](#3.2 迭代器操作)
[4. 算法(Algorithms)](#4. 算法(Algorithms))
[4.1 非修改算法](#4.1 非修改算法)
[4.2 修改算法](#4.2 修改算法)
[4.3 排序与查找](#4.3 排序与查找)
[5. 函数对象与 Lambda](#5. 函数对象与 Lambda)
[6. 字符串(string)](#6. 字符串(string))
[7. 综合实战案例](#7. 综合实战案例)
[8. 常见错误与最佳实践](#8. 常见错误与最佳实践)
1. STL 概述
STL(Standard Template Library,标准模板库)是 C++ 标准库的核心组成部分,由 Alexander Stepanov 设计,于 1994 年被纳入 C++ 标准。STL 以泛型编程(Generic Programming)为核心思想,通过模板(Template)机制实现了高度可复用的数据结构与算法。
STL 由三大核心组件构成:
- 容器(Containers):存储数据的数据结构,如 vector、list、map 等。
- 迭代器(Iterators):连接容器与算法的桥梁,提供统一的遍历接口。
- 算法(Algorithms):对容器中数据进行操作的函数模板,如排序、查找、变换等。
💡 提示: 使用 STL 前需包含对应头文件,如 #include <vector>、#include <algorithm> 等。
1.1 STL 的优势
| 优势 |
说明 |
| 高效性 |
底层实现经过高度优化,时间复杂度有保证 |
| 通用性 |
基于模板,支持任意数据类型 |
| 可扩展性 |
可自定义分配器、比较器等 |
| 标准化 |
跨平台、跨编译器一致行为 |
| 代码复用 |
避免重复造轮子,减少 Bug |
2. 容器(Containers)
容器是 STL 的基础,用于存储和管理数据。根据内部结构和使用场景,STL 容器分为四大类:
| 类别 |
代表容器 |
底层结构 |
| 顺序容器 |
vector / list / deque / array |
数组 / 链表 / 双端队列 |
| 关联容器 |
map / set / multimap / multiset |
红黑树(有序) |
| 无序容器 |
unordered_map / unordered_set |
哈希表 |
| 容器适配器 |
stack / queue / priority_queue |
基于其他容器封装 |
2.1 顺序容器
2.1.1 vector --- 动态数组
vector 是最常用的顺序容器,底层为连续内存数组,支持随机访问,尾部插入/删除效率为 O(1),中间插入/删除为 O(n)。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 1. 创建与初始化
vector<int> v1; // 空 vector
vector<int> v2(5, 0); // 5 个 0
vector<int> v3 = {1, 2, 3, 4, 5}; // 初始化列表
vector<int> v4(v3.begin(), v3.end()); // 从迭代器构造
// 2. 添加元素
v1.push_back(10); // 尾部追加
v1.push_back(20);
v1.emplace_back(30); // 原地构造,比 push_back 更高效
// 3. 访问元素
cout << v3[0] << endl; // 下标访问(不检查越界)
cout << v3.at(1) << endl; // at() 访问(越界抛异常)
cout << v3.front() << endl; // 第一个元素
cout << v3.back() << endl; // 最后一个元素
// 4. 遍历
for (int x : v3) cout << x << " "; // 范围 for
cout << endl;
for (auto it = v3.begin(); it != v3.end(); ++it)
cout << *it << " "; // 迭代器遍历
cout << endl;
// 5. 插入与删除
v3.insert(v3.begin() + 2, 99); // 在索引 2 处插入 99
v3.erase(v3.begin() + 2); // 删除索引 2 处元素
v3.pop_back(); // 删除最后一个元素
// 6. 容量管理
cout << "size: " << v3.size() << endl; // 元素个数
cout << "capacity: " << v3.capacity() << endl; // 已分配容量
v3.reserve(100); // 预分配 100 个元素的空间
v3.shrink_to_fit(); // 释放多余容量
v3.clear(); // 清空所有元素
// 7. 排序
vector<int> nums = {5, 2, 8, 1, 9, 3};
sort(nums.begin(), nums.end()); // 升序
sort(nums.begin(), nums.end(), greater<int>()); // 降序
for (int x : nums) cout << x << " ";
return 0;
}
💡 提示: reserve() 可避免频繁扩容导致的内存重分配,当预知元素数量时应提前调用。
2.1.2 list --- 双向链表
list 底层为双向链表,任意位置插入/删除为 O(1),但不支持随机访问(无 [] 运算符)。适合频繁插入删除的场景。
#include <list>
int main() {
list<int> lst = {3, 1, 4, 1, 5, 9, 2, 6};
// 头尾操作
lst.push_front(0); // 头部插入
lst.push_back(7); // 尾部插入
lst.pop_front(); // 删除头部
lst.pop_back(); // 删除尾部
// 在迭代器位置插入
auto it = lst.begin();
advance(it, 2); // 移动迭代器到第 3 个位置
lst.insert(it, 100); // 在该位置前插入 100
// 删除特定值
lst.remove(1); // 删除所有值为 1 的元素
// 排序(list 有自己的 sort,不能用 std::sort)
lst.sort(); // 升序排序
lst.sort(greater<int>()); // 降序排序
// 去重(需先排序)
lst.unique(); // 删除相邻重复元素
// 合并两个有序 list
list<int> lst2 = {2, 4, 6};
lst.merge(lst2); // lst2 合并到 lst,lst2 变为空
for (int x : lst) cout << x << " ";
return 0;
}
2.1.3 deque --- 双端队列
deque(double-ended queue)支持在头部和尾部高效插入/删除(O(1)),同时支持随机访问。底层由多个固定大小的内存块组成。
#include <deque>
int main() {
deque<int> dq = {3, 4, 5};
dq.push_front(2); // 头部插入
dq.push_front(1);
dq.push_back(6); // 尾部插入
cout << dq[0] << endl; // 随机访问,输出 1
cout << dq.at(2) << endl; // 输出 3
dq.pop_front(); // 删除头部
dq.pop_back(); // 删除尾部
for (int x : dq) cout << x << " "; // 2 3 4 5
return 0;
}
2.1.4 array --- 固定大小数组
array 是对 C 风格数组的封装,大小在编译期确定,不可动态扩容,但提供了 STL 风格的接口。
#include <array>
int main() {
array<int, 5> arr = {1, 2, 3, 4, 5};
cout << arr.size() << endl; // 5
cout << arr.front() << endl; // 1
cout << arr.back() << endl; // 5
cout << arr[2] << endl; // 3
// 支持 STL 算法
sort(arr.begin(), arr.end(), greater<int>());
for (auto x : arr) cout << x << " "; // 5 4 3 2 1
return 0;
}
2.2 关联容器
关联容器基于红黑树实现,元素自动有序,查找/插入/删除时间复杂度均为 O(log n)。
2.2.1 map --- 键值对映射
map 存储 key-value 对,key 唯一且自动升序排列。
#include <map>
#include <string>
int main() {
map<string, int> scores;
// 插入元素(三种方式)
scores["Alice"] = 95; // 下标赋值
scores.insert({"Bob", 87}); // insert + 初始化列表
scores.emplace("Charlie", 92); // emplace 原地构造
// 访问
cout << scores["Alice"] << endl; // 95
cout << scores.at("Bob") << endl; // 87(不存在则抛异常)
// 查找
auto it = scores.find("Charlie");
if (it != scores.end())
cout << it->first << ": " << it->second << endl;
// 判断 key 是否存在
if (scores.count("Dave") == 0)
cout << "Dave not found" << endl;
// 遍历(按 key 升序)
for (auto& [key, val] : scores) // C++17 结构化绑定
cout << key << " -> " << val << endl;
// 删除
scores.erase("Bob");
scores.erase(scores.begin()); // 删除第一个元素
cout << "size: " << scores.size() << endl;
return 0;
}
💡 提示: scores["key"] 若 key 不存在会自动插入默认值(0),建议用 find() 或 count() 先判断。
2.2.2 set --- 唯一元素集合
set 存储唯一元素,自动升序排列,常用于去重和有序集合操作。
#include <set>
int main() {
set<int> s = {5, 3, 1, 4, 1, 5, 9}; // 重复元素自动去除
// s 内容: {1, 3, 4, 5, 9}
s.insert(2); // 插入 2
s.erase(3); // 删除 3
// 查找
if (s.find(4) != s.end())
cout << "4 exists" << endl;
// 范围查找
auto lo = s.lower_bound(3); // 第一个 >= 3 的迭代器
auto hi = s.upper_bound(7); // 第一个 > 7 的迭代器
for (auto it = lo; it != hi; ++it)
cout << *it << " "; // 4 5
// 遍历
for (int x : s) cout << x << " "; // 1 2 4 5 9
return 0;
}
2.2.3 multimap 与 multiset
multimap 允许重复 key,multiset 允许重复元素,其余行为与 map/set 相同。
#include <map>
#include <set>
int main() {
// multimap: 同一 key 可对应多个 value
multimap<string, int> mm;
mm.insert({"math", 90});
mm.insert({"math", 85});
mm.insert({"english", 78});
// 获取某 key 的所有值
auto range = mm.equal_range("math");
for (auto it = range.first; it != range.second; ++it)
cout << it->second << " "; // 90 85
// multiset: 允许重复元素
multiset<int> ms = {1, 2, 2, 3, 3, 3};
cout << ms.count(3) << endl; // 3(值为 3 的元素个数)
ms.erase(2); // 删除所有值为 2 的元素
for (int x : ms) cout << x << " "; // 1 3 3 3
return 0;
}
2.3 无序容器(哈希容器)
无序容器基于哈希表实现,平均查找/插入/删除时间复杂度为 O(1),但元素无序。适合对性能要求高、不需要有序的场景。
2.3.1 unordered_map
#include <unordered_map>
#include <string>
int main() {
unordered_map<string, int> umap;
// 插入
umap["apple"] = 3;
umap["banana"] = 5;
umap.emplace("cherry", 2);
// 访问与查找
cout << umap["apple"] << endl; // 3
if (umap.count("banana"))
cout << "banana: " << umap["banana"] << endl;
// 遍历(顺序不确定)
for (auto& [k, v] : umap)
cout << k << "=" << v << " ";
// 性能参数
cout << "bucket_count: " << umap.bucket_count() << endl;
cout << "load_factor: " << umap.load_factor() << endl;
umap.reserve(100); // 预分配桶数量,减少 rehash
return 0;
}
2.3.2 unordered_set
#include <unordered_set>
int main() {
unordered_set<int> us = {3, 1, 4, 1, 5, 9, 2, 6};
// 重复的 1 自动去除,顺序不确定
us.insert(7);
us.erase(3);
if (us.find(5) != us.end())
cout << "5 found" << endl;
cout << "size: " << us.size() << endl;
return 0;
}
| 容器 |
有序 vs 无序 / 时间复杂度 |
| map / set |
有序(红黑树),O(log n) |
| unordered_map / unordered_set |
无序(哈希表),平均 O(1) |
| 适用场景 |
需要有序用 map/set;追求速度用 unordered_* |
2.4 容器适配器
容器适配器是对底层容器的封装,提供特定的访问接口,限制了部分操作以满足特定数据结构语义。
2.4.1 stack --- 栈(LIFO)
#include <stack>
int main() {
stack<int> st;
st.push(1); // 入栈
st.push(2);
st.push(3);
cout << st.top() << endl; // 3(查看栈顶,不弹出)
cout << st.size() << endl; // 3
while (!st.empty()) {
cout << st.top() << " "; // 3 2 1
st.pop(); // 弹出栈顶
}
return 0;
}
2.4.2 queue --- 队列(FIFO)
#include <queue>
int main() {
queue<int> q;
q.push(1); // 入队
q.push(2);
q.push(3);
cout << q.front() << endl; // 1(队头)
cout << q.back() << endl; // 3(队尾)
while (!q.empty()) {
cout << q.front() << " "; // 1 2 3
q.pop(); // 出队
}
return 0;
}
2.4.3 priority_queue --- 优先队列(堆)
priority_queue 默认为最大堆(堆顶为最大值),可通过比较器改为最小堆。
#include <queue>
#include <vector>
#include <functional>
int main() {
// 最大堆(默认)
priority_queue<int> maxHeap;
maxHeap.push(3);
maxHeap.push(1);
maxHeap.push(4);
maxHeap.push(1);
maxHeap.push(5);
while (!maxHeap.empty()) {
cout << maxHeap.top() << " "; // 5 4 3 1 1
maxHeap.pop();
}
cout << endl;
// 最小堆
priority_queue<int, vector<int>, greater<int>> minHeap;
minHeap.push(3);
minHeap.push(1);
minHeap.push(4);
minHeap.push(1);
minHeap.push(5);
while (!minHeap.empty()) {
cout << minHeap.top() << " "; // 1 1 3 4 5
minHeap.pop();
}
return 0;
}
3. 迭代器(Iterators)
迭代器是 STL 的核心抽象,提供了一种统一的方式来遍历不同类型的容器,使算法与容器解耦。迭代器的行为类似于指针。
3.1 迭代器分类
| 类型 |
支持操作 |
代表容器 |
| 输入迭代器(Input) |
单向读取,只能前进 |
istream_iterator |
| 输出迭代器(Output) |
单向写入,只能前进 |
ostream_iterator |
| 前向迭代器(Forward) |
单向读写,可多次遍历 |
forward_list |
| 双向迭代器(Bidirectional) |
双向读写(++ 和 --) |
list, map, set |
| 随机访问迭代器(Random Access) |
支持 +n、-n、[] |
vector, deque, array |
3.2 迭代器操作详解
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
int main() {
vector<int> v = {1, 2, 3, 4, 5};
// ── 基本迭代器操作 ──
auto it = v.begin(); // 指向第一个元素
auto end = v.end(); // 指向最后一个元素的下一位
cout << *it << endl; // 解引用,输出 1
++it; // 前进
cout << *it << endl; // 输出 2
it += 2; // 随机访问迭代器可跳跃
cout << *it << endl; // 输出 4
// ── 反向迭代器 ──
for (auto rit = v.rbegin(); rit != v.rend(); ++rit)
cout << *rit << " "; // 5 4 3 2 1
cout << endl;
// ── const 迭代器(只读)──
for (auto cit = v.cbegin(); cit != v.cend(); ++cit)
cout << *cit << " "; // 不能通过 cit 修改元素
cout << endl;
// ── advance 与 distance ──
auto it2 = v.begin();
advance(it2, 3); // 移动 3 步,指向 v[3]=4
cout << *it2 << endl; // 4
cout << distance(v.begin(), it2) << endl; // 3
// ── next 与 prev ──
auto it3 = next(v.begin(), 2); // 返回 begin+2 的迭代器
auto it4 = prev(v.end(), 1); // 返回 end-1 的迭代器
cout << *it3 << " " << *it4 << endl; // 3 5
// ── 插入迭代器 ──
vector<int> dest;
copy(v.begin(), v.end(), back_inserter(dest)); // 尾部插入
copy(v.begin(), v.end(), front_inserter(dest)); // 头部插入(需 deque/list)
// ── 流迭代器 ──
// 从标准输入读取整数到 vector
// vector<int> input_v(istream_iterator<int>(cin), istream_iterator<int>());
// 输出到标准输出
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
return 0;
}
4. 算法(Algorithms)
STL 提供了超过 100 个算法函数模板,定义在 <algorithm> 和 <numeric> 头文件中。所有算法通过迭代器操作容器,与容器类型无关。
4.1 非修改算法
非修改算法不改变容器内容,只进行查找、统计、比较等操作。
#include <algorithm>
#include <vector>
#include <numeric>
int main() {
vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
// find --- 查找第一个匹配元素
auto it = find(v.begin(), v.end(), 5);
if (it != v.end())
cout << "found 5 at index: " << distance(v.begin(), it) << endl; // 4
// find_if --- 按条件查找
auto it2 = find_if(v.begin(), v.end(), [](int x){ return x > 7; });
cout << "first > 7: " << *it2 << endl; // 9
// count --- 统计元素个数
cout << "count(1): " << count(v.begin(), v.end(), 1) << endl; // 2
// count_if --- 按条件统计
int even_cnt = count_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });
cout << "even count: " << even_cnt << endl; // 3
// all_of / any_of / none_of
cout << all_of(v.begin(), v.end(), [](int x){ return x > 0; }) << endl; // 1(true)
cout << any_of(v.begin(), v.end(), [](int x){ return x > 8; }) << endl; // 1(true)
cout << none_of(v.begin(), v.end(), [](int x){ return x < 0; }) << endl; // 1(true)
// min_element / max_element
auto minIt = min_element(v.begin(), v.end());
auto maxIt = max_element(v.begin(), v.end());
cout << "min=" << *minIt << " max=" << *maxIt << endl; // min=1 max=9
// accumulate --- 求和(在 <numeric> 中)
int sum = accumulate(v.begin(), v.end(), 0);
cout << "sum: " << sum << endl; // 39
// accumulate 自定义操作(求乘积)
int product = accumulate(v.begin(), v.begin()+4, 1, multiplies<int>());
cout << "product of first 4: " << product << endl; // 12
return 0;
}
4.2 修改算法
修改算法会改变容器中的元素值或结构。
#include <algorithm>
#include <vector>
int main() {
vector<int> v = {1, 2, 3, 4, 5};
vector<int> dest(5);
// copy --- 复制
copy(v.begin(), v.end(), dest.begin());
// dest: {1, 2, 3, 4, 5}
// fill --- 填充
fill(dest.begin(), dest.end(), 0);
// dest: {0, 0, 0, 0, 0}
// generate --- 用函数生成值
int n = 0;
generate(v.begin(), v.end(), [&n]{ return n++ * 2; });
// v: {0, 2, 4, 6, 8}
// transform --- 变换每个元素
vector<int> v2 = {1, 2, 3, 4, 5};
vector<int> result(5);
transform(v2.begin(), v2.end(), result.begin(),
\](int x){ return x \* x; }); // 平方
// result: {1, 4, 9, 16, 25}
// transform 双范围版本(两个容器对应元素相加)
vector\ a = {1,2,3}, b = {10,20,30}, c(3);
transform(a.begin(), a.end(), b.begin(), c.begin(), plus\());
// c: {11, 22, 33}
// replace --- 替换特定值
vector\ v3 = {1, 2, 3, 2, 1};
replace(v3.begin(), v3.end(), 2, 99);
// v3: {1, 99, 3, 99, 1}
// replace_if --- 按条件替换
replace_if(v3.begin(), v3.end(), \[\](int x){ return x \> 50; }, 0);
// v3: {1, 0, 3, 0, 1}
// remove + erase 惯用法(erase-remove idiom)
vector\ v4 = {1, 2, 3, 2, 4, 2, 5};
v4.erase(remove(v4.begin(), v4.end(), 2), v4.end());
// v4: {1, 3, 4, 5}
// unique + erase(去除相邻重复,需先排序)
vector\ v5 = {1,1,2,3,3,3,4,5,5};
v5.erase(unique(v5.begin(), v5.end()), v5.end());
// v5: {1, 2, 3, 4, 5}
// reverse --- 反转
vector\ v6 = {1, 2, 3, 4, 5};
reverse(v6.begin(), v6.end());
// v6: {5, 4, 3, 2, 1}
// rotate --- 旋转
vector\ v7 = {1, 2, 3, 4, 5};
rotate(v7.begin(), v7.begin() + 2, v7.end());
// v7: {3, 4, 5, 1, 2}(以第3个元素为新起点)
return 0;
}
### 4.3 排序与查找算法
#include \
#include \
#include \
int main() {
vector\ v = {5, 2, 8, 1, 9, 3, 7, 4, 6};
// ── 排序 ──
sort(v.begin(), v.end()); // 升序
sort(v.begin(), v.end(), greater\()); // 降序
sort(v.begin(), v.end(), \[\](int a, int b){ // 自定义比较
return a % 3 \< b % 3; // 按模3余数排序
});
// stable_sort --- 稳定排序(相等元素保持原相对顺序)
vector\\> ps = {{2,"b"},{1,"a"},{2,"c"},{1,"d"}};
stable_sort(ps.begin(), ps.end(),
\[\](auto\& a, auto\& b){ return a.first \< b.first; });
// 结果: {1,a},{1,d},{2,b},{2,c} 相同 key 保持原顺序
// partial_sort --- 部分排序(只排前 k 个)
vector\ v2 = {5, 2, 8, 1, 9, 3};
partial_sort(v2.begin(), v2.begin()+3, v2.end());
// 前3个有序: {1, 2, 3, ...}
// nth_element --- 第 n 小的元素归位
vector\ v3 = {5, 2, 8, 1, 9, 3};
nth_element(v3.begin(), v3.begin()+2, v3.end());
cout \<\< "3rd smallest: " \<\< v3\[2\] \<\< endl; // 3
// ── 二分查找(需先排序)──
vector\ sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// binary_search --- 判断是否存在
cout \<\< binary_search(sorted.begin(), sorted.end(), 5) \<\< endl; // 1
// lower_bound --- 第一个 \>= target 的位置
auto lb = lower_bound(sorted.begin(), sorted.end(), 5);
cout \<\< "lower_bound(5): index " \<\< distance(sorted.begin(), lb) \<\< endl; // 4
// upper_bound --- 第一个 \> target 的位置
auto ub = upper_bound(sorted.begin(), sorted.end(), 5);
cout \<\< "upper_bound(5): index " \<\< distance(sorted.begin(), ub) \<\< endl; // 5
// equal_range --- 返回 \[lower_bound, upper_bound) 对
vector\ v4 = {1,2,2,2,3,4};
auto \[lo, hi\] = equal_range(v4.begin(), v4.end(), 2);
cout \<\< "count of 2: " \<\< distance(lo, hi) \<\< endl; // 3
// ── 排列 ──
vector\ perm = {1, 2, 3};
do {
for (int x : perm) cout \<\< x \<\< " ";
cout \<\< endl;
} while (next_permutation(perm.begin(), perm.end()));
// 输出 {1,2,3} 的全部 6 种排列
return 0;
}
## 5. 函数对象与 Lambda 表达式
函数对象(Functor)和 Lambda 表达式是 STL 算法的重要配套工具,用于自定义算法的行为。
### 5.1 内置函数对象(\)
STL 在 \ 中提供了一系列内置函数对象:
| **函数对象** | **等价操作** | **示例** |
|------------------|----------|-----------------------------------------------|
| plus\ | a + b | accumulate(v.begin(),v.end(),0,plus\()) |
| minus\ | a - b | transform(...) |
| multiplies\ | a \* b | accumulate(...,1,multiplies\()) |
| divides\ | a / b | transform(...) |
| modulus\ | a % b | transform(...) |
| negate\ | -a | transform(...) |
| equal_to\ | a == b | find_if(...) |
| less\ | a \< b | sort(...,less\()) |
| greater\ | a \> b | sort(...,greater\()) |
| logical_and\ | a \&\& b | all_of(...) |
| logical_or\ | a \|\| b | any_of(...) |
### 5.2 自定义函数对象
#include \
#include \
#include \
// 自定义函数对象:判断是否能被 n 整除
struct DivisibleBy {
int n;
DivisibleBy(int n) : n(n) {}
bool operator()(int x) const { return x % n == 0; }
};
// 自定义比较器:按绝对值排序
struct AbsCompare {
bool operator()(int a, int b) const {
return abs(a) \< abs(b);
}
};
int main() {
vector\ v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用自定义函数对象
int cnt = count_if(v.begin(), v.end(), DivisibleBy(3));
cout \<\< "divisible by 3: " \<\< cnt \<\< endl; // 3
vector\ v2 = {-5, 3, -1, 4, -2};
sort(v2.begin(), v2.end(), AbsCompare());
// v2: {-1, -2, 3, 4, -5}
return 0;
}
### 5.3 Lambda 表达式(C++11 起)
Lambda 是匿名函数,语法为:\[捕获列表\](参数列表) -\> 返回类型 { 函数体 }
#include \
#include \
#include \
int main() {
// ── 基本 Lambda ──
auto add = \[\](int a, int b) -\> int { return a + b; };
cout \<\< add(3, 4) \<\< endl; // 7
// ── 捕获外部变量 ──
int threshold = 5;
vector\ v = {1, 3, 5, 7, 9, 2, 4, 6, 8};
// \[=\] 值捕获(拷贝)
auto gt = \[=\](int x){ return x \> threshold; };
int cnt = count_if(v.begin(), v.end(), gt);
cout \<\< "count \> 5: " \<\< cnt \<\< endl; // 4
// \[\&\] 引用捕获(可修改外部变量)
int sum = 0;
for_each(v.begin(), v.end(), \[\&sum\](int x){ sum += x; });
cout \<\< "sum: " \<\< sum \<\< endl; // 45
// \[threshold\] 只捕获特定变量
auto between = \[threshold\](int x){ return x \> threshold \&\& x \< threshold + 4; };
cnt = count_if(v.begin(), v.end(), between);
cout \<\< "between 5 and 9: " \<\< cnt \<\< endl;
// ── mutable Lambda(修改值捕获的变量)──
int counter = 0;
auto inc = \[counter\]() mutable { return ++counter; };
cout \<\< inc() \<\< " " \<\< inc() \<\< " " \<\< inc() \<\< endl; // 1 2 3
cout \<\< "original counter: " \<\< counter \<\< endl; // 0(未改变)
// ── 在 STL 算法中使用 Lambda ──
vector\ words = {"banana", "apple", "cherry", "date"};
sort(words.begin(), words.end(),
\[\](const string\& a, const string\& b){ return a.size() \< b.size(); });
// 按字符串长度排序: date apple banana cherry
// ── std::function 存储 Lambda ──
function\ multiply = \[\](int a, int b){ return a \* b; };
cout \<\< multiply(6, 7) \<\< endl; // 42
return 0;
}
## 6. 字符串(std::string)
std::string 是 STL 提供的字符串类,封装了 C 风格字符串,提供了丰富的操作接口,是 C++ 中处理文本的标准方式。
#include \
#include \
#include \
int main() {
// ── 创建与初始化 ──
string s1 = "Hello, World!";
string s2(5, 'A'); // "AAAAA"
string s3 = s1.substr(0, 5); // "Hello"
// ── 基本操作 ──
cout \<\< s1.length() \<\< endl; // 13
cout \<\< s1.size() \<\< endl; // 13(同 length)
cout \<\< s1.empty() \<\< endl; // 0(false)
cout \<\< s1\[0\] \<\< endl; // H
cout \<\< s1.at(1) \<\< endl; // e
cout \<\< s1.front() \<\< endl; // H
cout \<\< s1.back() \<\< endl; // !
// ── 拼接 ──
string s4 = s3 + " STL"; // "Hello STL"
s4 += "!"; // "Hello STL!"
s4.append(" Great"); // "Hello STL! Great"
// ── 查找 ──
string text = "the quick brown fox jumps over the lazy dog";
size_t pos = text.find("fox");
if (pos != string::npos)
cout \<\< "fox at: " \<\< pos \<\< endl; // 16
pos = text.rfind("the"); // 从后往前找
cout \<\< "last the at: " \<\< pos \<\< endl; // 31
pos = text.find_first_of("aeiou"); // 第一个元音字母
cout \<\< "first vowel at: " \<\< pos \<\< endl; // 2
// ── 替换与修改 ──
string s5 = "Hello World";
s5.replace(6, 5, "STL"); // 从位置6替换5个字符
cout \<\< s5 \<\< endl; // "Hello STL"
s5.insert(5, " Beautiful"); // 在位置5插入
cout \<\< s5 \<\< endl; // "Hello Beautiful STL"
s5.erase(5, 10); // 从位置5删除10个字符
cout \<\< s5 \<\< endl; // "Hello STL"
// ── 大小写转换 ──
string s6 = "Hello World";
transform(s6.begin(), s6.end(), s6.begin(), ::toupper);
cout \<\< s6 \<\< endl; // "HELLO WORLD"
transform(s6.begin(), s6.end(), s6.begin(), ::tolower);
cout \<\< s6 \<\< endl; // "hello world"
// ── 数字与字符串互转 ──
int num = 42;
string numStr = to_string(num); // int -\> string
int back = stoi(numStr); // string -\> int
double d = stod("3.14"); // string -\> double
cout \<\< numStr \<\< " " \<\< back \<\< " " \<\< d \<\< endl;
// ── stringstream 分割字符串 ──
string csv = "apple,banana,cherry,date";
stringstream ss(csv);
string token;
vector\ tokens;
while (getline(ss, token, ','))
tokens.push_back(token);
for (auto\& t : tokens) cout \<\< t \<\< " ";
// apple banana cherry date
// ── 比较 ──
string a = "apple", b = "banana";
cout \<\< (a \< b) \<\< endl; // 1(字典序)
cout \<\< (a == b) \<\< endl; // 0
cout \<\< a.compare(b) \<\< endl; // 负数(a \< b)
return 0;
}
## 7. 综合实战案例
以下通过几个完整的实战案例,展示 STL 各组件的综合运用。
### 7.1 单词频率统计
使用 map 统计文本中每个单词出现的频率,并按频率降序输出 Top-N。
#include \
#include \