C++ 具名要求:序列容器 (SequenceContainer)
来自cppreference.com
序列容器 (SequenceContainer) 是在线性排列中存储相同类型对象的容器 (Container) 。
要求
凡例 | |
X
|
序列容器类 |
T
|
X 的元素类型
|
a | X 类型的值
|
u | 被声明的变量名 |
A
|
X 的分配器类型:
|
i,j | 老式输入迭代器 (LegacyInputIterator) ,[ i, j) 是有效范围,并且这些迭代器所指代的元素可隐式转换到 value_type
|
rg (C++23 起) | 实现了 container-compatible-range<T> 的类型 R 的值
|
il (C++11 起) | std::initializer_list<value_type> 类型的值 |
n | X::size_type 类型的值
|
p | 到 a 中的有效常量迭代器 |
q | 到 a 中的有效可解引用常量迭代器 |
q1,q2 | 到 a 中的两个常量迭代器,使得 [ q1, q2) 是有效范围
|
t | X::value_type 类型的左值或 const 右值 (C++11 起)
|
rv (C++11 起) | X::value_type 类型的非 const 右值
|
Args (C++11 起)
|
模板形参包 |
args (C++11 起) | 模式为 Args&& 的函数形参包
|
在满足以下所有条件时,X
是序列容器 (SequenceContainer) :
- 类型
X
满足容器 (Container) 。 - 下列语句和表达式必须合法,且对除 std::array 之外的(见注解) (C++11 起)所有序列容器均具有所指定的效果:
语句 | 效果 | 条件[1] | ||
---|---|---|---|---|
X u(n, t) | 构造保有 n 个 t 的副本的序列容器 | 前 | T 可复制插入 (CopyInsertable) 到 X
| |
后 | std::distance(u.begin(), u.end()) == n | |||
X u(i, j) | 构造与范围 [ i, j) 逐元素相等的序列容器
|
前 | T 从 *i 可就位构造 (EmplaceConstructible) 到 X 中
| |
后 | std::distance(u.begin(), u.end()) == std::distance(i, j) | |||
表达式 | 类型 | 效果 | 条件 | |
X(std::from_range, rg) (C++23 起) |
X
|
构造与范围 rg 逐元素相等的序列容器 | 前 | T 从 *ranges::begin(rg) 可就位构造 (EmplaceConstructible) 到 X 中
|
后 |
| |||
X(il) (C++11 起) |
X
|
等价于 X(il.begin(), il.end()) |
无明确要求 | |
a = il (C++11 起) |
X&
|
将 il 所表示的范围赋值到 a 中。[2] | 前 | T 可复制插入 (CopyInsertable) 且可复制赋值 (CopyAssignable)
|
后 | a 的既存元素被销毁或被赋值 | |||
a.emplace(p, args) (C++11 起) |
iterator
|
在 p 前插入以 std::forward<Args> (args) 构造的 T 类型的对象
|
前 | T 可复制插入 (CopyInsertable)
|
后 | 返回的迭代器指向由 args 构造到 a 中的元素 | |||
a.insert(p, t) | iterator
|
在 p 前插入 t 的副本 | 前 | T 可复制插入 (CopyInsertable)
|
后 | 返回的迭代器指向插入到 a 中的 t 的副本 | |||
a.insert(p, rv) (C++11 起) |
iterator
|
在 p 前插入 rv 的副本,可能使用移动语义 | 前 | T 可移动插入 (MoveInsertable)
|
后 | 返回的迭代器指向插入到 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 中
|
后 |
| |||
a.insert_range(p, rg) (C++23 起) |
iterator
|
插入 rg 中元素的副本到 p 之前 | 前 |
|
后 |
| |||
a.insert(p, il) (C++11 起) |
iterator
|
等价于 a.insert(p, il.begin(), il.end()) |
前 | 无明确要求 |
后 | 返回的迭代器指向插入到 a 中的首元素的副本,或当 il 为空时返回 p | |||
a.erase(q) | iterator
|
擦除 q 指向的元素 | 前 | 无明确要求 |
后 | 返回的迭代器指向擦除前紧跟 q 之后的元素,或在此类元素不存在时返回 a.end() | |||
a.erase(q1, q2) | iterator
|
擦除 [ q1, q2) 中的元素
|
前 | 无明确要求 |
后 | 返回的迭代器指向在任何擦除前 q2 曾指向的元素,或在此类元素不存在时返回 a.end() | |||
a.clear() | void | 销毁 a 中所有元素 | 前 | 无明确要求 |
后 |
| |||
a.assign(i, j) | void | 以 [ i, j) 的副本替换 a 中的元素
|
前 |
|
后 | [ i, j) 中的每个迭代器都只会解引用一次
| |||
a.assign_range(rg) (C++23 起) |
void | 以 rg 中每个元素的副本替换 a 中的元素 | 前 |
|
后 |
| |||
a.assign(il) (C++11 起) |
void | 等价于 a.assign(il.begin(), |
无明确要求 | |
a.assign(n, t) | void | 用 t 的 n 个副本替换 a 中的元素 | 前 | T 可复制插入 (CopyInsertable) 并可复制赋值 (CopyAssignable)
|
后 | 无明确要求 | |||
注 | ||||
|
可选操作
下列表达式必须合法,且对于所指名的序列容器拥有所指定的效果,prepend_range
和 append_range
以外的 (C++23 起)所有操作都会在均摊常数时间内完成:
表达式 | 类型 | 效果 | 前条件[1] | 容器 |
---|---|---|---|---|
a.front() | reference ;
对于 const a 是 |
返回 *a.begin() | 无明确要求 | std::basic_string std::array std::deque std::forward_list std::inplace_vector std::list std::vector |
a.back() | reference ;
对于 const a 是 |
等价于 auto tmp = a.end(); --tmp; return *tmp;。 |
无明确要求 | std::basic_string std::array std::deque std::inplace_vector std::list std::vector |
a.emplace_front(args) (C++11 起) |
void | 前附一个以 std::forward<Args> (args)... 构造的 T
|
T 从 args 可就位构造 (EmplaceConstructible) 到 X 中
|
std::deque std::forward_list std::list |
a.emplace_back(args) (C++11 起) |
void | 后附一个以 std::forward<Args> (args)... 构造的 T
|
T 从 args 可就位构造 (EmplaceConstructible) 到 X 中
|
std::deque std::inplace_vector std::list std::vector |
a.push_front(t) | void | 前附 t 的一个副本 | T 可复制插入 (CopyInsertable) 到 X 中
|
std::deque std::forward_list std::list |
a.push_front(rv) (C++11 起) |
void | 前附 rv 的一个副本,可能用移动语义 | T 可移动插入 (MoveInsertable) 到 X 中
| |
a.prepend_range(rg) (C++23 起) |
void | 插入[2] rg 中的元素的副本到 begin() 前,rg 中的每个迭代器都只会解引用一次 | T 从 *ranges::begin(rg) 可就位构造 (EmplaceConstructible) 到 X 中
|
std::deque std::forward_list std::list |
a.push_back(t) | void | 后附 t 的一个副本 | T 可复制插入 (CopyInsertable) 到 X 中
|
std::basic_string std::deque std::inplace_vector std::list std::vector |
a.push_back(rv) (C++11 起) |
void | 后附 rv 的一个副本,可能用移动语义 | T 可移动插入 (MoveInsertable) 到 X 中
| |
a.append_range(rg) (C++23 起) |
void | 插入[2] rg 中的元素的副本到 end() 前,rg 中的每个迭代器都只会解引用一次 | T 从 *ranges::begin(rg) 可就位构造 (EmplaceConstructible) 到 X 中
|
std::deque std::inplace_vector 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::inplace_vector std::list std::vector |
a[n] | reference ;
对于 const a 是 |
返回 *(a.begin() + n) | 无明确要求 | std::basic_string std::array std::deque std::inplace_vector std::vector |
a.at(n) | reference ;
对于 const a 是 |
返回 *(n + a.begin()),在 n >= size() 时会抛出 std::out_of_range | 无明确要求 | |
注 | ||||
另外,对于每个序列容器:
- 对于接收两个输入迭代器的构造函数模板,以及成员函数
insert()
、append()
、assign()
、replace()
的接受两个输入迭代器的模板重载,如果相应的模板实参不是老式输入迭代器 (LegacyInputIterator) ,那么它们不参与重载决议。
|
(C++17 起) |
标准库中的序列容器
存储并操作字符序列 (类模板) | |
(C++11) |
固定大小的原位连续数组 (类模板) |
动态的连续数组 (类模板) | |
(C++26) |
可动态调整大小的固定容量原位连续数组 (类模板) |
双端队列 (类模板) | |
(C++11 起) |
单链表 (类模板) |
双链表 (类模板) |
权衡/使用备注
std::vector | 快速访问,但大多情况的插入/删除低效。 |
std::inplace_vector | 快速访问,原位连续存储,但容量固定且大多情况的插入/删除低效。 |
std::array | 快速访问,原位连续存储,但元素数量固定且不支持插入/删除。 |
std::deque | 快速访问,可在序列首/尾而非中部高效地插入/删除 |
std::list std::forward_list |
在序列中部可高效地插入/删除,但访问效率大多为线性时间。 |
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 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
|
LWG 3927 | C++98 | operator[] 没有隐式要求 | 添加隐式要求 |