目录
1、std::deque ( double-ended queue ,双端队列)是有下标顺序容器
1、std::forward_list 是支持从容器中的任何位置快速插入和移除元素的容器
1、std::list 是支持常数时间从容器任何位置插入和移除元素的容器。不支持快速随机访问。
1、std::map 是有序键值对容器,它的元素的键是唯一的。
1、multimap 是关联容器,含有关键-值 pair 的已排序列表,同时容许多个入口拥有同一关键。
1、std::queue 类是容器适配器,它给予程序员队列的功能——尤其是 FIFO (先进先出)数据结构。
1、std::stack 类是容器适配器,它给予程序员栈的功能——特别是 FILO (先进后出)数据结构。该类模板表现为底层容器的包装器——只提供特定函数集合。栈从被称作栈顶的容器尾部推弹元素。
2、std::pmr::vector 是使用多态分配器的模板别名。
1、std::set 是关联容器,含有 Key 类型对象的已排序集。用比较函数 比较 (Compare) 进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现。
一、std::array(
封装固定大小数组的容器)
定义于头文件 |
||
template< class T, |
1、std::array 是封装固定大小数组的容器。
2、容器描述:
此容器是一个聚合类型,其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数组,它不会自动退化成 T* 。它能作为聚合类型聚合初始化,只要有至多 N
个能转换成 T
的初始化器;
3、使用方法
std::array<int, 3> a = {1,2,3}; 。
4、std::array优点
该结构体结合了 C 风格数组的性能、可访问性与容器的优点,比如可获取大小、支持赋值、随机访问迭代器等。std::array
满足容器 (Container) 和可逆容器 (ReversibleContainer) 的要求,除了默认构造的 array 是非空的,以及进行交换的复杂度是线性,它满足连续容器 (ContiguousContainer) (C++17 起)的要求并部分满足序列容器 (SequenceContainer) 的要求。
5、注意点
当其长度为零时 array
( N == 0
)有特殊情况。此时, array.begin() == array.end() ,并拥有某个唯一值。在零长 array
上调用 front() 或 back() 是未定义的。
亦可将 array
当做拥有 N
个同类型元素的元组。
6、代码实例
#include <string>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <array>
int main()
{
// 用聚合初始化构造
std::array<int, 3> a1{ {1, 2, 3} }; // CWG 1270 重申前的 C++11 中要求双花括号
// ( C++11 之后的版本和 C++14 起不要求)
std::array<int, 3> a2 = {1, 2, 3}; // = 后决不要求
std::array<std::string, 2> a3 = { std::string("a"), "b" };
// 支持容器操作
std::sort(a1.begin(), a1.end());
std::reverse_copy(a2.begin(), a2.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
// 支持带范围 for 循环
for(const auto& s: a3)
std::cout << s << ' ';
}
7、结果
3 2 1 a b
二、std::deque (双端队列)
定义于头文件 |
||
template< class T, |
(1) | |
namespace pmr { template <class T> |
(2) | (C++17 起) |
1、std::deque
( double-ended queue ,双端队列)是有下标顺序容器
它允许在其首尾两段快速插入及删除。另外,在 deque 任一端插入或删除不会非法化指向其余元素的指针或引用。
与 std::vector 相反, deque 的元素不是相接存储的:典型实现用单独分配的固定大小数组的序列,外加额外的登记,这表示下标访问必须进行二次指针解引用,与之相比 vector 的下标访问只进行一次。
2、deque 的存储按需自动扩展及收缩
扩张 deque 比扩展 std::vector 便宜,因为它不涉及到复制既存元素到新内存位置。另一方面, deque 典型地拥有较大的最小内存开销;只保有一个元素的 deque 必须分配其整个内部数组(例如 64 位 libstdc++ 上为对象大小 8 倍; 64 位 libc++ 上为对象大小 16 倍或 4096 字节的较大者)。
deque 上常见操作的复杂度(效率)如下:
- 随机访问——常数 O(1)
- 在结尾或起始插入或移除元素——常数 O(1)
- 插入或移除元素——线性 O(n)
std::deque
满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 和可逆容器 (ReversibleContainer) 的要求。
3、模板形参
T | - | 元素的类型。
|
||||
Allocator | - | 用于获取/释放内存及构造/析构内存中元素的分配器。类型必须满足分配器 (Allocator) 的要求。若 Allocator::value_type 与 T 不同则行为未定义。 |
4、迭代器非法化
操作 | 被非法化 |
---|---|
所有只读操作 | 决不 |
swap 、 std::swap | 尾后迭代器可能被非法化(实现定义) |
shrink_to_fit 、 clear 、 insert 、 emplace 、 push_front 、 push_back 、 emplace_front 、 emplace_back |
始终 |
erase | 若在起始擦除——仅被擦除元素 若在末尾擦除——仅被擦除元素和尾后迭代器 |
resize | 若新大小小于旧者:仅被擦除元素和尾后迭代器 若新大小大于旧者:非法化所有迭代器 |
pop_front | 仅有指向被擦除元素者 |
pop_back | 仅有指向被擦除元素者和尾后迭代器 |
5、非法化注意
- 从 deque 任一端插入时, insert 和 emplace 不会非法化引用。
- push_front 、 push_back 、 emplace_front 和 emplace_back 不会非法化任何到 deque 元素的引用。
- 从 deque 任一端擦除时, erase 、 pop_front 和 pop_back 不会非法化到未擦除元素的引用。
- 以较小的大小调用 resize 不会非法化任何到未擦除元素的引用。
- 以较大的大小调用 resize 不会非法化任何到 deque 元素的引用。
6、成员类型
成员类型 | 定义 | ||||
value_type |
T |
||||
allocator_type |
Allocator |
||||
size_type |
无符号整数类型(通常是 std::size_t ) | ||||
difference_type |
有符号整数类型(通常是 std::ptrdiff_t ) | ||||
reference |
|
||||
const_reference |
|
||||
pointer |
|
||||
const_pointer |
|
||||
iterator |
遗留随机访问迭代器 (LegacyRandomAccessIterator) | ||||
const_iterator |
常随机访问迭代器 | ||||
reverse_iterator |
std::reverse_iterator<iterator> | ||||
const_reverse_iterator |
std::reverse_iterator<const_iterator> |
7、代码实例
#include <iostream>
#include <deque>
int main()
{
// 创建容纳整数的 deque
std::deque<int> d = {7, 5, 16, 8};
// 从 deque 的首尾添加整数
d.push_front(13);
d.push_back(25);
// 迭代并打印 deque 的值
for(int n : d) {
std::cout << n << '\n';
}
}
8、结果
13 7 5 16 8 25
三、std::forward_list
定义于头文件 |
||
template< class T, |
(1) | (C++11 起) |
namespace pmr { template <class T> |
(2) | (C++17 起 |
1、std::forward_list
是支持从容器中的任何位置快速插入和移除元素的容器
std::forward_list
不支持快速随机访问。它实现为单链表,且实质上与其在 C 中实现相比无任何开销。与 std::list 相比,此容器提在不需要双向迭代时提供更有效地利用空间的存储。
在链表内或跨数个链表添加、移除和移动元素,不会非法化当前指代链表中其他元素的迭代器。然而,在从链表移除元素(通过 erase_after )时,指代对应元素的迭代器或引用会被非法化。
std::forward_list
满足容器 (Container) (除了 operator==
的复杂度始终为线性和 size 函数)、具分配器容器 (AllocatorAwareContainer) 和序列容器 (SequenceContainer) 的要求。
2、模板形参
T | - | 元素的类型。
|
||||
Allocator | - | 用于获取/释放内存及构造/析构内存中元素的分配器。类型必须满足分配器 (Allocator) 的要求。若 Allocator::value_type 与 T 不同则行为未定义。 |
3、成员类型
成员类型 | 定义 |
value_type |
T |
allocator_type |
Allocator |
size_type |
无符号整数类型(通常是 std::size_t ) |
difference_type |
有符号整数类型(通常是 std::ptrdiff_t ) |
reference |
value_type& |
const_reference |
const value_type& |
pointer |
std::allocator_traits<Allocator>::pointer |
const_pointer |
std::allocator_traits<Allocator>::const_pointer |
iterator |
遗留向前迭代器 (LegacyForwardIterator) |
const_iterator |
常向前迭代器 |
4、代码实例
#include <forward_list&g