C++ STL标准模板库

一、前言

STL:Standard Template Library(标准模板库或泛型库),是C++标准库的组成部分。STL借助模板把常用的数据结构及其算法实现了一次,并且做到了数据结构和算法的分离。STL已完全被内置到支持 C++ 的编译器中,无需额外安装,这可能也是STL被广泛使用的原因之一。STL是以源代码的形式提供的。根本上来说,STL是一些容器(封装有数据结构的模板类)、算法和其他的一些组件的集合,基本达到了各种存储方法和相关算法的高度优化。

STL的版本

HP STL

Alexandar Stepanov(STL 标准模板库之父)与 Meng Lee 合作完成。是开放源码的。

SGI STL

HP STL的一个继承版本,开源、可读性好

STLport

为了使 SGI STL 的基本代码都适用于 VC++ 和 C++ Builder 等多种编译器而提出的,开源

PL STL

参照 HP STL 实现出来的,也是 HP STL 的一个继承版本,因此该头文件中不仅含有 HP STL 的相关授权信息,同时还有 P.J.Plauger 本人的版权信息。非开源。

Rouge Wave STL

由 Rouge Wave 公司开发的,也是继承 HP STL 的一个版本,它也不是开源的。

二、STL的基本组成

STL是由容器、算法、迭代器、函数对象、适配器、内存分配器6部分构成,其中迭代器、函数对象、适配器、内存分配器是为容器、算法服务。

组成部分 含义
容器 一些封装数据结构的模板类
算法 STL 提供了非常多(大约 100 个)的数据结构算法,它们都被设计成一个个的模板函数,这些算法在 std 命名空间中定义,其中大部分算法都包含在头文件 <algorithm> 中,少部分位于头文件 <numeric> 中
迭代器 对容器中数据的读和写,是通过迭代器完成的,扮演着容器和算法之间的胶合剂
函数对象 一个类将 () 运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象(又称仿函数)
适配器 可以使一个类的接口(模板的参数)适配成用户指定的形式,从而让原本不能在一起工作的两个类工作在一起。值得一提的是,容器、迭代器和函数都有适配器
内存分配器 为容器类模板提供自定义的内存申请和释放功能

在 C++ 标准中,STL被重新组织为13个头文件,如下:

<iterator> <functional> <vector> <deque> <list>
<queue> <stack> <set> <map> <algorithm>
<numeric> <memory> <utility>

注意:
或许是为了向下兼容,或许是为了内部组织规划,某些 STL 版本同时存储具备扩展名和无扩展名的两份文件,建议最好遵照C++规范,使用无扩展名的头文件

三、容器是什么

在实际的开发过程中,存取数据的方式会直接影响到对它们进行增删改查操作的复杂程度和时间消耗。
简单的理解容器,就是一些模板类的集合,但和普通模板类不同的是,容器中封装的是组织数据的方法(也就是数据结构)。STL 提供有3类标准容器,分别是序列容器、排序容器和哈希容器,其中后两类容器有时也统称为关联容器,如下表:

容器种类 功能
序列容器 主要包括 vector 向量容器、list 列表容器以及 deque 双端队列容器。之所以被称为序列容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的。将元素插入容器时,指定在什么位置,元素就会位于什么位置。
排序容器 包括 set 集合容器、multiset多重集合容器、map映射容器以及 multimap 多重映射容器。排序容器中的元素默认是由小到大排序好的,即便是插入元素,元素也会插入到适当位置。所以关联容器在查找时具有非常好的性能。
哈希容器 C++ 11 新加入 4 种关联式容器,分别是 unordered_set 哈希集合、unordered_multiset 哈希多重集合、unordered_map 哈希映射以及 unordered_multimap 哈希多重映射。和排序容器不同,哈希容器中的元素是未排序的,元素的位置由哈希函数确定。

以上3类容器的存储方式完全不同,因此使用不同容器完成相同操作的效率也大不相同。因此在实际使用中,要根据具体的功能选择最适合的容器。

四、迭代器

无论是序列容器还是关联容器,最常做的操作无疑是遍历容器中存储的元素,而实现此操作,多数情况会选用“迭代器(iterator)”来实现。
虽然不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,所以容器有一些操作方法是类似的,因此完全可以利用泛型的技术,将其设计成适用所有容器的通用算法,从未将容器和算法分离。

1、迭代器类别

STL标准库为每一种标准容器定义了一种迭代器类型,即不同容器的迭代器不同,因此容器的迭代器功能的强弱也不同,进而决定了容器是否哦支持STL中的某些算法。
常用的迭代器按功能强弱分为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器 5 种。输入迭代器和输出迭代器比较特殊,它们不是把数组或容器当做操作对象,而是把输入流/输出流作为操作对象。关于输入迭代器和输出迭代器在这里暂时不多讲。

假设存在一个迭代器Iter

1)前向迭代器(forward iterator)

Iter支持++Iter、Iter++、*Iter操作、被复制或赋值、可使用==和!=运算符进行比较

2)双向迭代器(bidirectional iterator)

双向迭代器具有正向迭代器的全部功能,除此之外,还可以进行 --Iter 或者 Iter-- 操作(即一次向后移动一个位置)。

3)随机访问迭代器(random access iterator)

随机访问迭代器具有双向迭代器的全部功能。除此之外,假设 i 是一个整型变量或常量,则 Iter 还支持以下操作:

操作 说明
Iter+=i 使得 Iter 往后移动 i 个元素
Iter-=i 使得 Iter 往前移动 i 个元素
Iter+i 返回 Iter 后面第 i 个元素的迭代器
Iter-i 返回 Iter 前面第 i 个元素的迭代器
Iter[i] 返回 Iter 后面第 i 个元素的引用

两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。另外,表达式 p2-p1 也是有定义的,其返回值表示 p2 所指向元素和 p1 所指向元素的序号之差。

五、容器对应的迭代器

1、对应关系

容器 迭代器类别
array 随机访问迭代器
vector 随机访问迭代器
deque 随机访问迭代器
list 双向迭代器
set / multiset 双向迭代器
map / multimap 双向迭代器
forward_list 前向迭代器
unordered_map / unordered_multimap 前向迭代器
unordered_set / unordered_multiset 前向迭代器
stack 不支持迭代器
queue 不支持迭代器

注意:
容器适配器 stack 和 queue 没有迭代器,它们包含有一些成员函数,可以用来对元素进行访问。

2、迭代器的定义方式

迭代器类别 格式
正向迭代器 容器类名::iterator 迭代器名;
常量正向迭代器 容器类名::const_iterator 迭代器名;
反向迭代器 容器类名::reverse_iterator 迭代器名;
常量反向迭代器 容器类名::const_reverse_iterator 迭代器名;

说明:
*迭代器名:迭代器指向的元素
常量迭代器和非常量迭代器的分别在于:通过非常量迭代器还能修改其指向的元素
反向迭代器和正向迭代器的区别在于:对正向迭代器进行 ++ 操作时,迭代器会指向容器中的后一个元素;而对反向迭代器进行 ++ 操作时,迭代器会指向容器中的前一个元素。
以上 4 种定义迭代器的方式,并不是每个容器都适用。

六、总结

序列式容器.png
关联式容器.png
无序关联式容器.png
适配器.png
迭代器适配器.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容