1. 基本认识

标准模板库(Standard Template Library,简称STL)定义了一套概念体系,为泛型程序设计提供了逻辑基础STL中的各个类模板、函数模板的参数都是用这个体系中的概念来规定的。使用STL的模板时,类型参数既可以是C++标准库中已有的类型,也可以是自定义的类型——只要这些类型是所要求概念的模型。

  • 概念:用来界定具备一定功能的数据类型。例如:

将“可以比大小的所有数据类型(有比较运算符)”这一概念记为Comparable将“具有公有的复制构造函数并可以用‘=’赋值的数据类型”这一概念记为Assignable将“可以比大小、具有公有的复制构造函数并可以用‘=’赋值的所有数据类型”这个概念记作Sortable。

  • 子概念:对于两个不同的概念A和B,如果概念A所需求的所有功能也是概念B所需求的功能,那么就

说概念B是概念A的子概念。例如:Sortable既是Comparable的子概念,也是Assignable的子概念

  • 模版:符合一个概念的数据类型称为该概念的模型,例如:

int型是Comparable概念的模型。静态数组类型不是Assignable概念的模型(无法用“=”给整个静态数组赋值)v模型:符合一个概念的数据类型称为该概念的模型,例如:int型是Comparable概念的模型。静态数组类型不是Assignable概念的模型(无法用“=”给整个静态数组赋值)

2. 基本组件

STL的基本组件包括容器、迭代器、函数对象、算法

(1)容器

容纳、包含一组元素的对象。

a. 基本容器类模板

顺序容器array(数组)、vector(向量)、deque(双端队列)、forward_list(单链表)、list(列表)(有序)关联容器set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)无序关联容器unordered_set (无序集合)、unordered_multiset(无序多重集合)unordered_map(无序映射)、unorder_multimap(无序多重映射)容器适配器stack(栈)、queue(队列)、priority_queue(优先队列)

//按照与容器所关联的迭代器类型划分:可逆容器随机访问容器

b. 容器的功能(语法)

  • 通用功能

1) 默认构造函数构造空容器

2) 支持关系运算符:==、!=、<、<=、>、>=

3) begin()、end():获得容器首、尾迭代器

4) clear():将容器清空

5) empty():判断容器是否为空

6) size():得到容器元素个数

7) s1.swap(s2):将s1和s2两容器内容交换

  • 可逆容器的特性

S::reverse_iterator:逆向迭代器类型S::const_reverse_iterator:逆向常迭代器类型rbegin() :指向容器尾的逆向迭代器rend():指向容器首的逆向迭代器

  • 随机访问容器的特性

[]《个人经验》在没有特殊数据结构的情况下只常用 vector和map vector用于存储,功能强大;map键值访问使用

(2)迭代器

a. 迭代器的功能

迭代器本身是泛化的指针Iterators(迭代器)是算法和容器的桥梁。将迭代器作为算法的参数、通过迭代器来访问容器而不是把容器直接作为算法的参数。

b. 迭代器的分类关系

随机访问迭代器->双向迭代器->前向迭代器->输入迭代器

  • 输出迭代器

输入:从序列读取数据; 输出:向序列写入数据前向迭代器既是输入迭代器又是输出迭代器,允许单向遍历;双向迭代器在前向的基础上允许反向遍历;

c. 迭代器的区间

两个迭代器表示一个区间:[p1, p2),包含p1,但不包含p2合法的区间:当且仅当p1经过n次(n ≥0)自增(++)操作后满足p1 == p2

d. 迭代器的辅助函数

advance(p, n)

对p执行n次自增操作

distance(first, last)

计算两个迭代器first和last的距离,即对first执行多少次“++”操作后能够使得first == last

3. 顺序容器的接口

以vector为例,记忆熟练为主

(1)初始化操作

构造函数默认构造/有参构造/拷贝构造列表初始化

vector<int> arr = {1,4,5,7};

(2)通用性

begin() end()//获得容器首、尾迭代器
clear()//将容器清空
empty()//判断容器是否为空
size()//得到容器元素个数
s1.swap(s2)//将s1和s2两容器内容交换

(3)双向访问性

S::reverse_iterator //逆向迭代器类型
S::const_reverse_iterator //逆向常迭代器类型
rbegin() //指向容器尾的逆向迭代器
rend() //指向容器首的逆向迭代器

(4)随机访问性

s[n]

(5)读写特性

//插入函数
insert(iterator pos, const T& v),   在pos位置插入后,返回新插入元素的迭代器
push_front()(只对list和deque)          push_back()
emplace_front()   emplace()   emplace_back()
//这些操作构造而不是拷贝元素到容器中,分别对应push_front、insert 和push_back

其他:vector:

s.capacity() //返回当前容量
s.reserve(n) //若容量小于n,则对s进行扩展,使其容量至少为n

list:将 中

s1.splice(p, s2, q1, q2) // s2 [q1, q2)    移动到s1中p所指向元素之前

forward_list:

1) 单向链表每个结点只有指向下个结点的指针,没有简单的方法来获取一个结点的前驱

2) 未定义insert、emplace和erase操作,而定义了insert_after、emplace_after和erase_after操作,

其参数与list的insert、emplace和erase相同,但并不是插入或删除迭代器p1所指的元素,而是对p1所指元素之后的结点进行操作

3) 不支持size操作

array:

1) array是对内置数组的封装,提供了更安全,更方便的使用数组的方式

2) array的对象的大小是固定的,定义时除了需要指定元素类型,还需要指定容器大小。

3) 不能动态地改变容器大小

4. 关联容器的接口

插入

insert() //
erase() //删除
find()  //查找
返回第一个指向不大于x的迭代器
lower_bound(x) //
upper_bound() //返回第一个指向不小于x的迭代器
equal_range(iterator first,iterator second,val)
//equal_range() 适用于已排序的范围。如果范围未排序,结果将是不确定的。
//返回找到的val的迭代器范围;如果范围内没有找到等于 val 的元素,first 和 second 都会指
向 last。
count(iterator first,iterator second,val) //计数:范围内等于val的元素个数

多重(multi_):允许有多个相同元素无序(unordered_):不排序

//函数模版和算法部分见教材即可