文章目录
- C++标准模板库(STL)全面解析
-
- 一、STL概述
- 二、STL容器详解
-
- [1. 序列容器](#1. 序列容器)
-
- [(1) `vector`](#(1)
vector) - [(2) `deque`](#(2)
deque) - [(3) `list`](#(3)
list) - [(4) `forward_list`](#(4)
forward_list) - [(5) `array`](#(5)
array)
- [(1) `vector`](#(1)
- [2. 关联容器](#2. 关联容器)
-
- [(1) `set`](#(1)
set) - [(2) `multiset`](#(2)
multiset) - [(3) `map`](#(3)
map) - [(4) `multimap`](#(4)
multimap)
- [(1) `set`](#(1)
- [3. 无序关联容器(C++11)](#3. 无序关联容器(C++11))
-
- [(1) `unordered_set`](#(1)
unordered_set) - [(2) `unordered_multiset`](#(2)
unordered_multiset) - [(3) `unordered_map`](#(3)
unordered_map) - [(4) `unordered_multimap`](#(4)
unordered_multimap)
- [(1) `unordered_set`](#(1)
- [4. 容器适配器](#4. 容器适配器)
-
- [(1) `stack`](#(1)
stack) - [(2) `queue`](#(2)
queue) - [(3) `priority_queue`](#(3)
priority_queue)
- [(1) `stack`](#(1)
- 三、STL算法详解
-
- [1. 非修改序列算法](#1. 非修改序列算法)
- [2. 修改序列算法](#2. 修改序列算法)
- [3. 排序和相关操作](#3. 排序和相关操作)
- [4. 数值算法](#4. 数值算法)
- 四、迭代器详解
-
- [1. 迭代器类别](#1. 迭代器类别)
- [2. 迭代器操作](#2. 迭代器操作)
- [3. 迭代器适配器](#3. 迭代器适配器)
- 五、函数对象和Lambda表达式
-
- [1. 函数对象(Functor)](#1. 函数对象(Functor))
- [2. 预定义函数对象](#2. 预定义函数对象)
- [3. Lambda表达式(C++11)](#3. Lambda表达式(C++11))
- 六、STL高级特性
-
- [1. 分配器(Allocator)](#1. 分配器(Allocator))
- [2. 类型特性(Type Traits)](#2. 类型特性(Type Traits))
- [3. 智能指针(C++11)](#3. 智能指针(C++11))
- [4. 元组(C++11)](#4. 元组(C++11))
- 七、STL最佳实践
- 八、STL扩展与未来
-
- [1. C++17新增特性](#1. C++17新增特性)
- [2. C++20新增特性](#2. C++20新增特性)
- 九、总结
C++标准模板库(STL)全面解析
一、STL概述
C++标准模板库(Standard Template Library, STL)是C++标准库的重要组成部分,提供了一系列通用的模板类和函数,实现了常用的数据结构和算法。STL由Alexander Stepanov在20世纪90年代早期开发,后被纳入C++标准。
STL的六大组件
- 容器(Containers): 管理数据的集合
- 算法(Algorithms): 操作容器中数据的函数模板
- 迭代器(Iterators): 用于遍历容器元素的抽象
- 函数对象(Functors): 行为类似函数的对象
- 适配器(Adapters): 修改容器或函数对象接口的组件
- 分配器(Allocators): 管理内存分配的类模板
二、STL容器详解
1. 序列容器
(1) vector
动态数组,支持快速随机访问
cpp
#include <vector>
std::vector<int> v = {1, 2, 3};
v.push_back(4); // 添加元素
(2) deque
双端队列,支持首尾高效插入/删除
cpp
#include <deque>
std::deque<int> d = {1, 2, 3};
d.push_front(0); // 前端插入
(3) list
双向链表,支持任意位置高效插入/删除
cpp
#include <list>
std::list<int> l = {1, 2, 3};
l.insert(++l.begin(), 5); // 在第二个位置插入
(4) forward_list
单向链表,内存开销更小
cpp
#include <forward_list>
std::forward_list<int> fl = {1, 2, 3};
(5) array
固定大小数组,比原生数组更安全
cpp
#include <array>
std::array<int, 3> a = {1, 2, 3};
2. 关联容器
(1) set
有序唯一元素集合
cpp
#include <set>
std::set<int> s = {3, 1, 2};
(2) multiset
有序可重复元素集合
cpp
#include <set>
std::multiset<int> ms = {1, 1, 2};
(3) map
键值对集合,键唯一
cpp
#include <map>
std::map<std::string, int> m = {{"Alice", 25}, {"Bob", 30}};
(4) multimap
键可重复的键值对集合
cpp
#include <map>
std::multimap<std::string, int> mm;
3. 无序关联容器(C++11)
(1) unordered_set
哈希集合
cpp
#include <unordered_set>
std::unordered_set<int> us = {3, 1, 2};
(2) unordered_multiset
可重复哈希集合
cpp
#include <unordered_set>
std::unordered_multiset<int> ums;
(3) unordered_map
哈希表
cpp
#include <unordered_map>
std::unordered_map<std::string, int> um;
(4) unordered_multimap
键可重复哈希表
cpp
#include <unordered_map>
std::unordered_multimap<std::string, int> umm;
4. 容器适配器
(1) stack
后进先出(LIFO)栈
cpp
#include <stack>
std::stack<int> st;
st.push(1);
(2) queue
先进先出(FIFO)队列
cpp
#include <queue>
std::queue<int> q;
q.push(1);
(3) priority_queue
优先级队列
cpp
#include <queue>
std::priority_queue<int> pq;
pq.push(3); pq.push(1); pq.push(2);
三、STL算法详解
STL提供了约 100 100 100种算法,主要分为以下几类:
1. 非修改序列算法
cpp
#include <algorithm>
#include <vector>
std::vector<int> v = {1, 2, 3, 4, 5};
// 查找
auto it = std::find(v.begin(), v.end(), 3);
// 计数
int cnt = std::count(v.begin(), v.end(), 2);
// 遍历
std::for_each(v.begin(), v.end(), [](int x){ std::cout << x << " "; });
2. 修改序列算法
cpp
// 复制
std::vector<int> v2(5);
std::copy(v.begin(), v.end(), v2.begin());
// 填充
std::fill(v.begin(), v.end(), 0);
// 移除
auto new_end = std::remove(v.begin(), v.end(), 3);
v.erase(new_end, v.end());
3. 排序和相关操作
cpp
// 排序
std::sort(v.begin(), v.end());
// 二分查找
bool found = std::binary_search(v.begin(), v.end(), 3);
// 合并
std::vector<int> v3 = {1, 3, 5};
std::vector<int> v4 = {2, 4, 6};
std::vector<int> merged(6);
std::merge(v3.begin(), v3.end(), v4.begin(), v4.end(), merged.begin());
4. 数值算法
cpp
#include <numeric>
// 累加
int sum = std::accumulate(v.begin(), v.end(), 0);
// 内积
int product = std::inner_product(v.begin(), v.end(), v2.begin(), 0);
// 部分和
std::partial_sum(v.begin(), v.end(), v2.begin());
四、迭代器详解
迭代器是STL的核心概念之一,提供了访问容器元素的统一接口。
1. 迭代器类别
- 输入迭代器: 只读,单遍扫描
- 输出迭代器: 只写,单遍扫描
- 前向迭代器: 可读写,多遍扫描
- 双向迭代器: 可前后移动
- 随机访问迭代器: 支持指针算术运算
2. 迭代器操作
cpp
std::vector<int> v = {1, 2, 3, 4, 5};
// 获取迭代器
auto begin = v.begin();
auto end = v.end();
// 迭代器移动
auto it = begin;
++it; // 前进
--it; // 后退(双向迭代器)
it += 2; // 随机访问
// 解引用
int val = *it;
3. 迭代器适配器
cpp
#include <iterator>
// 反向迭代器
for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {
std::cout << *rit << " ";
}
// 插入迭代器
std::back_insert_iterator<std::vector<int>> back_it(v);
*back_it = 6; // 相当于push_back
// 流迭代器
std::istream_iterator<int> input_it(std::cin);
std::ostream_iterator<int> output_it(std::cout, " ");
五、函数对象和Lambda表达式
1. 函数对象(Functor)
cpp
struct Add {
int operator()(int a, int b) const {
return a + b;
}
};
Add add;
int sum = add(3, 4);
2. 预定义函数对象
cpp
#include <functional>
std::plus<int> add;
std::greater<int> gt;
std::logical_and<bool> land;
3. Lambda表达式(C++11)
cpp
auto lambda = [](int a, int b) { return a + b; };
int sum = lambda(3, 4);
// 捕获列表
int x = 10;
auto capture = [x](int y) { return x + y; };
六、STL高级特性
1. 分配器(Allocator)
cpp
#include <memory>
std::vector<int, std::allocator<int>> v;
2. 类型特性(Type Traits)
cpp
#include <type_traits>
static_assert(std::is_integral<int>::value, "int is integral");
3. 智能指针(C++11)
cpp
#include <memory>
std::unique_ptr<int> uptr(new int(5));
std::shared_ptr<int> sptr = std::make_shared<int>(10);
std::weak_ptr<int> wptr = sptr;
4. 元组(C++11)
cpp
#include <tuple>
auto t = std::make_tuple(1, "hello", 3.14);
int x = std::get<0>(t);
七、STL最佳实践
-
选择合适的容器:
- 需要随机访问:
vector - 频繁插入删除:
list - 键值对存储:
map/unordered_map
- 需要随机访问:
-
使用算法替代循环:
cpp// 不好 for (auto& x : v) { x *= 2; } // 更好 std::transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; }); -
利用移动语义(C++11):
cppstd::vector<std::string> v; std::string s = "data"; v.push_back(std::move(s)); // 移动而非复制 -
避免不必要的拷贝:
cpp// 不好 void process(std::vector<int> v) { ... } // 更好 void process(const std::vector<int>& v) { ... } void process(std::vector<int>&& v) { ... } // 移动语义 -
使用emplace操作:
cppstd::vector<std::pair<int, std::string>> v; v.emplace_back(1, "one"); // 直接在容器中构造
八、STL扩展与未来
1. C++17新增特性
-
结构化绑定:
cppstd::map<int, std::string> m = {{1, "one"}, {2, "two"}}; for (const auto& [key, value] : m) { std::cout << key << ": " << value << "\n"; } -
并行算法:
cpp#include <execution> std::sort(std::execution::par, v.begin(), v.end());
2. C++20新增特性
-
范围(Ranges):
cpp#include <ranges> auto even = [](int i) { return i % 2 == 0; }; for (int i : std::views::iota(0, 10) | std::views::filter(even)) { std::cout << i << " "; } -
概念(Concepts):
cpptemplate <std::input_iterator It> void process(It begin, It end) { ... }
九、总结
STL是C++编程中不可或缺的工具集,它提供了高效、通用的数据结构和算法实现。掌握STL不仅能提高编程效率,还能写出更简洁、更安全的代码。随着C++标准的演进,STL也在不断扩展和完善,为开发者提供更强大的功能。