C++STL
什么是STL?
STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。
STL的一个重要特点是数据结构和算法的分离。这是STL能够得到广泛复用的原因之一,例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组;
STL另一个重要特性是它不是面向对象的。对于OOP的三大特性,STL基本都不包含,相反,STL主要依赖于模板。另外,由于STL是基于模板的,其内联函数的大量使用使得生成的代码短小高效。
STL的六大组件
- 容器(Container),对应数据结构,如list,vector,和deque ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;
- 迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。从使用上来说,迭代器可以看成是指针。
- 算法(Algorithm),是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,需要注意的是,STL的算法都是基于模板的,因此对于简单或复杂的数据类型都是可行的。
- 仿函数(Functor),如果一个类将 () 运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象(又称仿函数)。
- 适配器(Adaptor),可以使一个类的接口(模板的参数)适配成用户指定的形式,从而让原本不能在一起工作的两个类工作在一起。值得一提的是,容器、迭代器和函数都有适配器。
- 分配器(allocator),为容器类模板提供自定义的内存申请和释放功能,由于往往只有高级用户才有改变内存分配策略的需求,因此内存分配器对于一般用户来说,并不常用。
容器
STL包括了很多种容器,但主要分类的话,可以如下分类:

头文件
在当前的标准模板库STL中,主要包括了以下十三个头文件,这是三个头文件也是使用STL的必须的头文件,分别封装了一定的数据结构与算法
iterator | functional | vector | deque |
---|---|---|---|
list | queue | stack | set |
map | algorithm | numeric | memory |
utility |
迭代器
无论是序列式容器还是关联式容器,我们都要对容器内部的元素执行各种操作,比如增删改查,但STL是为了让算法与容器分隔开的,对于不同类型的元素应该都可以采用同一种模式进行操作。基于此,迭代器就诞生了,迭代器与C的指针类似,它可以是需要的任意类型,通过迭代器可以指向容器中的某个元素,如果需要,还可以对该元素进行读/写操作。
迭代器分类
迭代器总共有五种,分为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器。
输入输出迭代器与另外三种迭代器不同,他们的操作对象是输入输出流,而另外三种迭代器操作容器。
正向迭代器(前向迭代器) | 顾名思义,正向迭代器支持“正向”的操作,也就是如果p是一个迭代器,那么我们可以对p执行p++,++p,*p,但不可以执行p--等“反向”操作,此外,正向迭代器还支持赋值、复制和比较 |
双向迭代器 | 可以使用正向迭代器的全部功能,除此之外还支持p--,--p |
随机访问迭代器 | 支持所有双向迭代器的操作,除此之外,随机访问迭代器还支持p += i,p -= i,p+i,p-i,p[i]这一系列更贴近真实的指针的操作,此外,两个随机访问迭代器还支持比较操作,也就是可以对两个随机访问迭代器进行< > <= >=的操作,此外,对于两个随机访问迭代器,p2-p1也有意义,类似于两个指针作差 |
需要注意的是,根据容器支持的迭代器的类型不同,其支持的算法也会有所不同。
对于STL中的容器,其支持的迭代器如下:
array | 随机访问迭代器 |
---|---|
vector | 随机访问迭代器 |
deque | 随机访问迭代器 |
list | 双向迭代器 |
set / multiset | 双向迭代器 |
map / multimap | 双向迭代器 |
forward_list | 前向迭代器 |
unordered_map / unordered_multimap | 前向迭代器 |
unordered_set / unordered_multiset | 前向迭代器 |
stack | 不支持迭代器 |
queue | 不支持迭代器 |
定义迭代器
定义一个迭代器,可以采用如下四种方式:
正向迭代器(前向迭代器) | 容器类名::iterator 迭代器名; |
常量正向迭代器 | 容器类名::const_iterator 迭代器名; |
反向迭代器(反向迭代器适配器) | 容器类名::reverse_iterator 迭代器名; |
常量反向迭代器 | 容器类名::const_reverse_iterator 迭代器名; |
迭代器的操作类似指针,使用*迭代器名即可访问对应的元素
常量与非常量迭代器只有能不能修改其指向的元素这一区别,而反向迭代器与正向迭代器的区别只在于对正向迭代器进行++操作会往后指一位,对反向则往前指一位。
需要指出的是,由于每个容器对于支持的迭代器类型不同,所以有的容器是不支持某些迭代器的,比如forward_list容器就只支持正向迭代器,不支持反向迭代器
基本STL及其用法:
序列式容器,戳这里!
怎么用关联式容器?
无序式关联式容器,基于哈希的数据结构
不懂容器适配器?戳这里!