1. 什么是 STL
STL(standard template libaray-标准模板库):是 C++ 标准库 的重要组成部分 ,不仅是一个可复用的组件库,而且是一个包罗 数据结构与算法 的软件框架。
2. STL 的版本
原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意
运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使
用。 HP 版本--所有STL实现版本的始祖。
P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,
符号命名比较怪异。
RW 版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。
SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,
可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习 STL 要阅读部分 源代码 ,
主要参考的就是这个版本。
3. STL 的六大组件

学习STL的三层境界:
1.熟用STL
2.了解其底层的原理
3.能扩展:根据需求扩展STL
3.1
在 C++ 中,容器(Containers) 和容器适配器(Container Adapters) 是 STL(标准模板库)中用于存储和管理数据的核心组件,二者既有联系又有区别:
一、容器(Containers):直接存储数据的基础结构
容器是用于存储和组织数据的通用数据结构,STL 提供了多种容器,每种容器有其独特的底层实现和适用场景。
核心特点:
-
直接管理数据元素的存储和访问,提供迭代器(iterator)用于遍历。
-
支持基本的增删查改操作(如
insert
、erase
、size
等)。
常见容器分类:
-
序列式容器:元素按顺序存储,强调元素的位置关系。
-
vector
:动态数组(连续空间) -
list
:双向链表 -
deque
:双端队列(分段连续空间) -
array
:固定大小数组(C++11 新增)
-
-
关联式容器:元素按键(key)存储,强调快速查找。
-
set
/map
:基于红黑树(有序,O (log n) 查找) -
unordered_set
/unordered_map
:基于哈希表(无序,O (1) 平均查找)
-
二、容器适配器(Container Adapters):基于容器的 "包装器"
容器适配器是对现有容器的封装,它屏蔽了底层容器的部分接口,只提供特定的操作方式,适配成另一种数据结构。
核心特点:
-
不直接存储数据,而是依赖一种底层容器(默认或指定)来实现功能。
-
没有迭代器,不支持随机访问,只提供适配后的数据结构的操作接口。
常见容器适配器:
-
stack
(栈):-
特性:后进先出(LIFO),只支持从顶部插入 / 删除元素。
-
底层容器:默认用
deque
,也可指定vector
或list
。 -
接口:
push
(入栈)、pop
(出栈)、top
(取栈顶)。
-
-
queue
(队列):-
特性:先进先出(FIFO),只支持从尾部插入、头部删除。
-
底层容器:默认用
deque
,也可指定list
(不能用vector
,因需高效头部删除)。 -
接口:
push
(入队)、pop
(出队)、front
(队头)、back
(队尾)。
-
-
priority_queue
(优先级队列):-
特性:每次出队的是 "优先级最高" 的元素(默认最大元素)。
-
底层容器:默认用
vector
,需支持随机访问,内部通过堆算法维护优先级。 -
接口:
push
(插入)、pop
(弹出最高优先级元素)、top
(取最高优先级元素)。
-
三、容器与容器适配器的核心区别
|-------|-------------------|----------------------------|
| 维度 | 容器(如vector、list) | 容器适配器(如stack、queue) |
| 数据存储 | 直接管理数据,有自己的底层结构 | 依赖底层容器存储数据(如stack默认用deque) |
| 接口开放性 | 提供丰富接口(迭代器、随机访问等) | 接口受限(仅适配后的数据结构操作) |
| 迭代器支持 | 支持迭代器遍历 | 不支持迭代器 |
| 功能定位 | 通用数据结构,灵活存储和访问 | 特定场景的数据结构(栈 / 队列 / 优先级队列) |
总结
-
容器是 STL 的基础数据结构,直接存储数据并提供灵活的访问方式。
-
容器适配器是对容器的二次封装,专注于特定的数据操作模式(如栈的 LIFO),简化了特定场景的使用。
例如:stack
本质是对deque
的包装,只开放栈相关的接口,隐藏了deque
的其他功能(如随机访问),让用户能更简单地使用 "栈" 这种数据结构。