STL 容器
顺序容器
实现按顺序访问的数据结构
1. array (C++11)
静态的连续数组,封装固定大小数组的容器
template<
class T, // 元素类型
std::size_t N //数组大小
> struct array;
特点
- 结合了 C 风格数组的性能,可访问性与容器可获取大小,支持赋值,随机访问迭代器等优点。
- 在连续的内存位置中储存对象
成员函数
元素访问
at() // 返回指定位置的引用,同时进行越界检查
operator[] // 访问指定位置的引用,无边界检查
front() // 返回首元素的引用,容器为空时,对 front 的调用是未定义的
back() // 返回最后一个元素的引用,容器为空时未定义
data() // 返回指向底层数组的指针,范围为 [data(), data() + size()],container.data() 优于 &container[0]
迭代器
begin() / cbegin() // 返回指向起始的迭代器
end() / cend() // 返回指向末尾的迭代器,为占位符,无法解引用
rbegin() / crbegin() // 返回指向起始的逆向迭代器
rend() / crend() // 返回指向末尾的逆向迭代器,为占位符,无法解引用
容量
empty() // 检查容器是否为空
size() // 返回容纳的元素数
max_size() // 返回可容纳的最大元素数
操作
fill() // 以指定值填充容器
swap() // 交换内容
2. vector
动态连续数组
template<
class T, // 元素类型,元素需满足可复制赋值,可复制构造,可擦除要求
class Allocator = std::allocator<T> // 分配器,负责封装堆内存管理的对象
> class vector;
特点
- 线性储存,可通过迭代器,也可通过指向元素的常规指针访问元素,实现快速随机访问
- 储存自动管理,按需扩展收缩。但通常会比静态数组占用更多空间,用以管理将来的增长。其只在额外内存耗尽时重分配。分配的内存总量可用
capacity()
函数查询,通过shrink_to_fit()
(C++11 起)可将多余内存释放。 - 如元素数量已知,可用
reserve()
提高capacity()
值,消除内存重分配 - 标准库对类型
bool
特化,为空间效率优化
成员函数
// 同 array,新增:
基本
get_allocator() // 返回相关分配器
容量
reserve() // 预留储存空间
capacity() // 返回当前储存空间能容纳的元素数
shrink_to_fit() // 释放未使用空间
修改
clear() // 清除内容
insert() // 插入元素
emplace() // 原位构造元素
erase() // 擦除元素
push_back() // 将元素添加到容器末尾
emplace_back() // 在末尾就地构造元素
pop_back() // 移除末元素
resize() // 改变容器可储存元素个数
swap() // 交换内容,仅整体交换,不会在单独元素上调用任何移动,复制或交换操作
迭代器失效
部分操作会使迭代器失效
// 只读操作不会导致失效
swap() // end() 失效
clear(), operator=, assign() // 全部失效
reserve(), shrink_to_fit() // vector 容量改变时,全部失效
erase() // 被擦除元素及之后的所有元素(包括 end()) 失效
push_back(), emplace_back() // vector 容量改变时全部失效,否则只有 end() 失效
insert(), emplace() // vector 容量改变时,全部失效,否则只有插入点和其后失效
resize() // vector 容量改变时全部失效,否则只有 end() 与被擦除元素
pop_back() // 被擦除元素及 end() 失效
3. deque (double-ended queue)
双端队列
template<
class T,
class Allocator = std::allocator<T>
> class deque;
特点
- 有下标顺序容器,允许在首尾两端快速插入及删除,且在任一端插入或删除不会使指向其余元素的指针或引用失效
- 不是连续存储的,典型实现为用单独分配的固定尺寸数组,外加额外的登记。这表示下标访问必须进行二次指针解引用,与之相比
vector
只需要一次 - 储存按需扩展收缩,扩张时,不涉及到复制元素到新位置。其拥有较大的最小内存开销,只保存一个元素时也需要分配整个内部数组
成员函数
//同 vector
迭代器失效
// 只读操作不会导致失效
swap() // end() 迭代器可能失效
shrink_to_fit(), clear(), insert(), emplace(), push_front(), //
push_back(), emplace_front(), emplace_back() // 全部失效
erase() // 如果起始擦除,则只有被擦除元素失效,如果在末尾擦除,则被擦除元素和 end() 失效。否则全部失效
resize() // 尺寸变大,则所有迭代器失效,尺寸变小,则只有被擦除元素和 end() 失效,尺寸不变,则无失效
pop_front() // 只有被擦除元素
pop_back() // 被擦除元素和 end()
4. forward_list (C++11)
单链表
template<
class T,
class Allocator = std::allocator<T>
> class forward_list;
特点
- 支持在任何位置进行快速插入删除,不支持快速随机访问,实现为单链表,与
std::list
(双链表) 相比,其在不需要双向迭代时有更高的空间效率 - 从链表移除元素时,指代对应元素的迭代器或引用会被非法化
成员函数
迭代器
before_begin() / cbefore_begin() // 返回指向第一个元素之前的迭代器
修改
insert_after() // 在元素后插入
emplace_after() // 在元素后原位构造
erase_after() // 擦除元素后的元素
push_front() // 插入元素到容器起始
emplace_front() // 在容器头部原位构造
pop_front() // 移除首元素
resize() // 改变容器中可储存元素的个数
swap() // 交换内容
操作
merge() // 合并两个已排序列表
splice_after() // 从另一个 forward_list 中移动元素
remove() / remove_if() // 移除满足特定标准的元素
reverse() // 将链表的所有元素顺序反转
unique() // 删除连续的重复元素
sort() // 对元素进行排序
5. list
双链表
template<
class T,
class Allocator = std::allocator<T>
> class list;
特点
- 支持在任何位置进行快速插入删除,不支持快速随机访问,通常实现方法为双链表,与
std::forward_list
相比,其提供双向迭代但在空间上效率较低。
成员函数
// 同 vector