C++ 具名要求:序列容器 (SequenceContainer)
序列容器 (SequenceContainer) 是在线性排列中存储相同类型对象的容器 (Container) 。
要求
以下情况下,类型 X 是序列容器 (SequenceContainer) :
- 类型
X是容器 (Container) ,且
给定
-
T,X的元素类型 -
A,X的分配器类型:在X::allocator_type存在时是该类型,否则是 std::allocator<T> - a,
X类型的左值表达式 - p,a 中的有效常量迭代器
- q,a 中的有效可解引用常量迭代器
- q1 与 q2,a 中的两个有效常量迭代器,并且
[q1,q2)是有效范围 - i 与 j,两个使得
[i,j)是有效范围,且各迭代器指代能隐式转换成value_type的对象的老式输入迭代器 (LegacyInputIterator) - il,std::initializer_list<value_type> 类型的对象
- n,
X::size_type类型的值 - t,
X::value_type类型的左值或 const 右值 - rv,是
X::value_type类型的非 const 右值 -
Args,模板形参包 - args,拥有模式
Args&&的函数形参包
下列表达式必须合法,且对除 std::array 之外的所有顺序容器均具有所指定的效果:
| 表达式 | 返回类型 | 效果 | 前条件 | 后条件 |
|---|---|---|---|---|
| X(n, t)
X a(n, t) |
构造保有 n 个 t 的副本的容器 | T 可复制插入 (CopyInsertable) 到 X
|
std::distance(begin(),end()) == n | |
| X(i, j)
X a(i, j) |
构造与范围 [i, j) 逐元素相等的顺序容器
|
T 从 *i 可就位构造 (EmplaceConstructible) 到 X 中
(仅对 std::vector)如果各迭代器不是老式向前迭代器 (LegacyForwardIterator) ,那么 |
std::distance(begin(), end()) == std::distance(i, j) | |
| X(il) | X(il.begin(), il.end()) | |||
| a = il | X& |
将 il 所表示的范围赋值到 a 中[1] | T 可复制插入 (CopyInsertable) 且可复制赋值 (CopyAssignable)
|
a 的既存元素被销毁或被赋值 |
| a.emplace(p, args) | iterator
|
在 p 前插入以 std::forward<Args>(args) 构造的 T 类型的对象
|
T 可复制插入 (CopyInsertable)
(对 std::vector 与 std::deque) |
返回指向由 args 构造到 a 中的元素的迭代器 |
| a.insert(p, t) | iterator
|
在 p 前插入 t 的副本 | T 可复制插入 (CopyInsertable)
(对 std::vector 与 std::deque) |
返回指向插入到 a 中的 t 的副本的迭代器 |
| a.insert(p, rv) | iterator
|
在 p 前插入 rv 的副本,可能用移动语义 | T 可移动插入 (MoveInsertable)
(对 std::vector 与 std::deque) |
返回指向插入到 a 中的 rv 的副本的迭代器 |
| a.insert(p, n, t) | iterator |
插入 n 个 t 的副本到 p 之前 | T 可复制插入 (CopyInsertable) 且可复制赋值 (CopyAssignable)
|
返回指向插入到 a 中的首元素的副本的迭代器,或当 n == 0 时返回 p
|
| a.insert(p, i, j) | iterator |
插入 [i, j) 中元素的副本到 p 之前
|
T 可就位构造 (EmplaceConstructible) 且 i 与 j 不在 a 中
(仅对 std::vector)如果迭代器不是老式向前迭代器 (LegacyForwardIterator) ,那么 |
[i, j) 中的每个迭代器被解引用一次。返回指向插入到 a 的首元素的副本的迭代器,或当 i == j 时返回 p
|
| a.insert(p, il) | iterator |
a.insert(p, il.begin(), |
返回指向插入到 a 中的首元素的副本的迭代器,或在 il 为空时返回 p。 | |
| a.erase(q) | iterator |
擦除 q 所指向的元素 | (std::deque, std::vector) T 可移动赋值 (MoveAssignable)
|
返回指向擦除前紧跟 q 之后的元素的迭代器,或在此种元素不存在时返回 a.end()。 |
| a.erase(q1, q2) | iterator |
擦除 [q1, q2) 中的元素 |
(std::deque, std::vector) T 可移动赋值 (MoveAssignable) |
返回指向在任何擦除前 q2 曾指向的元素的迭代器,或在不存在此种元素时返回 a.end()。 |
| a.clear() | void | 销毁 a 中所有元素 |
所有引用、指针及迭代器均失效,包含尾迭代器。a.empty() == true。 | |
| a.assign(i, j) | void | 以 [i, j) 的副本替换 a 中的元素
|
T 可就位构造 (EmplaceConstructible) ,且 i、j 不在 a 中
(std::vector),如果不是老式向前迭代器 (LegacyForwardIterator) ,那么 |
[i, j) 中的每个迭代器被解引用一次
|
| a.assign(il) | void | a.assign(il.begin(), il.end()) |
||
| a.assign(n, t) | void | 用 t 的 n 个副本替换 a 中的元素 | T 可复制插入 (CopyInsertable) 并可复制赋值 (CopyAssignable)
|
|
| 注 | ||||
| ||||
可选操作
下列表达式必须合法,且对于所指名的顺序容器拥有所指定的效果,所有操作都会在均摊常数时间内完成:
| 表达式 | 返回类型 | 效果 | 前条件 | 容器 |
|---|---|---|---|---|
| a.front() | reference
对于 const a 是 |
等价于 *a.begin() | (全部) | |
| a.back() | reference
对于 const a 是 |
等价于 { auto tmp = a.end(); --tmp; |
std::basic_string std::array std::deque std::list std::vector | |
| a.emplace_front(args) | void | 前附一个以 std::forward<Args>(args)... 构造的 T
|
T 从 args 可就位构造 (EmplaceConstructible) 到 X 中
|
std::deque std::forward_list std::list |
| a.emplace_back(args) | void | 后附一个以 std::forward<Args>(args)... 构造的 T
|
T 从 args 可就位构造 (EmplaceConstructible) 到 X 中
(仅 std::vector) |
std::deque std::list std::vector |
| a.push_front(t) | void | 前附 t 的一个副本 | T 可复制插入 (CopyInsertable) 到 X 中
|
std::deque std::forward_list std::list |
| a.push_front(rv) | void | 前附 rv 的一个副本,可能用移动语义 | T 可移动插入 (MoveInsertable) 到 X 中
|
std::deque std::forward_list std::list |
| a.push_back(t) | void | 后附 t 的一个副本 | T 可复制插入 (CopyInsertable) 到 X 中
|
std::basic_string std::deque std::list std::vector |
| a.push_back(rv) | void | 后附 rv 的一个副本,可能用移动语义 | T 可移动插入 (MoveInsertable) 到 X 中
|
std::basic_string std::deque std::list std::vector |
| a.pop_front() | void | 销毁首元素 | a.empty() == false | std::deque std::forward_list std::list |
| a.pop_back() | void | 销毁最末元素 | a.empty() == false | std::basic_string std::deque std::list std::vector |
| a[n] | reference
对于 const a 是 |
等价于 *(n + a.begin()) | std::basic_string std::array std::deque std::vector | |
| a.at(n) | reference
对于 const a 是 |
等价于 *(n + a.begin()),但在 n >= size() 时会抛出 std::out_of_range | std::basic_string std::array std::deque std::vector |
另外,对于每个顺序容器,接收两个输入迭代器的构造函数模板和成员函数 insert()、append()、assign()、replace() 的模板重载,若相应的模板实参不满足老式输入迭代器 (LegacyInputIterator) ,则它们不参与重载决议。
标准库中的顺序容器
| 存储并操作字符序列 (类模板) | |
| (C++11) |
静态的连续数组 (类模板) |
| 动态的连续数组 (类模板) | |
| 双端队列 (类模板) | |
| (C++11 起) |
单链表 (类模板) |
| 双链表 (类模板) |
权衡/使用备注
| std::vector | 快速访问但大多情况在插入/删除低效 |
| std::array | 快速访问但元素数量固定 |
| std::list std::forward_list |
在序列中部高效地插入/删除 |
| std::deque | 在序列首尾高效地插入/删除 |
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 139 | C++98 | 在指定的容器上也不需要实现可选操作 | 需要以均摊常数时间实现 |
| LWG 149 | C++98 | a.insert(p, t) 返回 iterator,但
a.insert(p, n, t) 和 a.insert(p, n, t) 返回 void |
都返回 iterator
|
| LWG 151 | C++98 | q1 可解引用[1] | 它不需要可解引用 |
| LWG 355 | C++98 | 调用 a.back() 或 a.pop_back() 会执行危险[2]的操作 --a.end() | 改成自减 a.end() 的副本 |
| LWG 589 | C++98 | i 和 j 指代的对象不一定可转换到 value_type
|
这些对象可以隐式转换到 value_type
|