STL(standard template libaray-标准模板库),是C++标准库的重要组成部分,包含了很多常用的数据结构和算法。
在我们学习了模板的之后,再来看STL,就能知道它是C++标准库中的模板类和模板函数的集合,作为可复用的库大大提高了程序员的工作效率。
STL主要组成包括:
- 容器(Containers):封装各种数据结构,如数组、链表、集合等。
- 算法(Algorithms):提供排序、查找、拷贝、合并等通用算法。
- 迭代器(Iterators):连接容器与算法的桥梁,用来遍历容器。
- 函数对象(Function Objects / Functors):行为像函数的对象,用于定制算法行为。
- 适配器(Adapters):对已有组件进行封装,使其接口发生变化(如 stack、queue)。
- 分配器(Allocators):负责内存分配,通常使用默认的分配器。
概要如下图所示:
说到STL,就不得不说到泛型编程,这也是上次提到过的一种编程方式。具体可以查看:【C++】Chaper03 函数模板与泛型-CSDN博客
接下来进行几个部分的大致介绍。
一、STL容器
容器大致分为三类,分别是序列式容器、关联式容器、无序容器。
1. 序列式容器(Sequence Containers)
保持元素的排列顺序。
vector
:动态数组,支持随机访问,尾部插入删除高效。deque
:双端队列,头尾插入删除都高效。list
:双向链表,任意位置插入删除高效,但不支持随机访问。forward_list
:C++11引入,单向链表。array
:定长数组,C++11引入。
2. 关联式容器(Associative Containers)
自动按键排序(通常为红黑树实现)。
set
:键的集合,不允许重复。multiset
:允许重复键。map
:键值对,键唯一。multimap
:键值对,键可重复。
3. 无序容器(Unordered Containers)
基于哈希表实现,C++11 引入。
unordered_set
、unordered_multiset
unordered_map
、unordered_multimap
二、迭代器(Iterators)
STL中的迭代器类似于指针,用于访问容器中的元素。
常见迭代器类型:
input_iterator
:只读,单向(如 istream_iterator)output_iterator
:只写,单向(如 ostream_iterator)forward_iterator
:可读写,单向(如 forward_list)bidirectional_iterator
:双向(如 list)random_access_iterator
:随机访问(如 vector、deque)
三、STL算法(Algorithms)
STL 提供了约 60 多种通用算法,主要分为以下几类:
- 非变序算法:不修改原始容器内容(如
find
、count
、for_each
) - 变序算法:可能会修改容器(如
copy
、replace
、remove
) - 排序和比较:
sort
、stable_sort
、min
、max
- 数值算法:
accumulate
、inner_product
(需#include <numeric>
)
四、函数对象(Function Objects)
函数对象是重载了 operator()
的类或结构体,可以像函数一样调用。常用于定制排序规则等。
例如:
struct MyCompare {bool operator()(int a, int b) {return a > b; // 降序}
};std::sort(vec.begin(), vec.end(), MyCompare());
五、适配器(Adapters)
对现有的容器或函数进行封装,改变其接口。
- 容器适配器:
stack
、queue
、priority_queue
- 迭代器适配器:
reverse_iterator
、insert_iterator
- 函数适配器:
bind
、not1
、mem_fun
(C++11推荐使用std::bind
和 Lambda)
六、分配器(Allocators)
用于抽象和管理内存的分配与释放。一般用默认的分配器,但也可以自定义内存管理策略。
标准分配器 std::allocator
:
std::allocator
是 C++ 标准库提供的默认分配器,实现了最基本的内存分配和对象管理功能。其定义位于头文件 中。主要成员函数包括:
- allocate:分配未构造的内存。
- deallocate:释放先前分配的内存。
- construct:在已分配的内存上构造对象(C++17 之前)。
- destroy:调用对象的析构函数(C++17 之前)2。
自定义分配器:
自定义分配器允许开发者控制内存管理策略。例如,可以实现一个内存池分配器,以减少频繁的内存分配和释放带来的开销。
STL的优点与缺点
STL的优点与缺点
优点:
- 高效:模板和内联使得STL非常高效。
- 通用:一套算法可作用于不同容器。
- 易用:编写高质量代码更容易。
缺点:
- 编译慢:模板膨胀严重。
- 错误提示晦涩难懂。
- 可定制性有限(例如自定义内存管理复杂)。