Namespaces
Variants

C++ named requirements: SequenceContainer

From cppreference.net
C++ named requirements

一个 SequenceContainer 是一种 Container ,它以线性排列方式存储相同类型的对象。

目录

要求

给定以下类型和值:

类型 定义
C 序列容器类
T C 的元素类型
A C 的分配器类型:
R (C++23 起) 满足 container-compatible-range  <T> 概念的类型
Args (C++11 起) 模板形参包
Iter C::iterator
Ref C::reference
CRef C::const_reference
定义
v 类型为 C 的值
cv 类型为 const C 的值
i , j 满足 [ i , j ) 有效范围 且迭代器所指元素可隐式转换为 C::value_type LegacyInputIterator
rg (C++23 起) 类型为 R 的值
il (C++11 起) 类型为 std:: initializer_list < C :: value_type > 的值
n 类型为 C::size_type 的值
p 指向 v 的有效 常量迭代器
q 指向 v 可解引用 常量迭代器
q1 , q2 指向 v 的常量迭代器,且满足 [ q1 , q2 ) 为有效范围
t 类型为 C::value_type (C++11 前) 左值 或常量右值 (C++11 起)
rv (C++11 起) 类型为 C::value_type 的非常量右值
args (C++11 起) 形如 Arg&& 的函数形参包

C 满足 SequenceContainer 的要求,当且仅当以下所有条件均成立:

  • C 满足 Container 的要求。
  • 下列语句和表达式是良构的,并具有指定语义:
基本操作
(标准库中所有序列容器必需 ,除 std::array (C++11 起)
声明 语义 [1]
C c ( n, t ) ; 效果 构造持有 n t 副本的序列容器。
前置条件

T 复制插入 C

(C++11 起)
后置条件 std:: distance ( c. begin ( ) , c. end ( ) ) n
C c ( i, j ) ; 效果 构造与范围 [ i , j ) 逐元素相等的序列容器。
  • 范围 [ i , j ) 中的每个迭代器恰好解引用一次。
前置条件

T 原位构造 C ,从 * i

(C++11 起)
后置条件 std:: distance ( c. begin ( ) , c. end ( ) ) std:: distance ( i, j )
表达式 类型 语义
C ( std:: from_range , rg )
(C++23 起)
C 效果 构造与范围 rg 逐元素相等的序列容器。
  • 范围 rg 中的每个迭代器恰好解引用一次。
前置条件 T 原位构造 X ,从 * ranges:: begin ( rg )
后置条件 std:: distance ( begin ( ) , end ( ) ) ranges:: distance ( rg )
C ( il )
(C++11 起)
C 等价于 C ( il. begin ( ) , il. end ( ) )
v = il
(C++11 起)
C& 效果 il 表示的范围赋值给 v [2]
返回值 * this
前置条件 T 复制插入 C 可复制赋值
后置条件 v 的现有元素或被销毁或被赋值。
v. emplace ( p, args )
(C++11 起)
Iter 效果 p 前插入一个类型为 T 的对象,使用 std:: forward < Args > ( args ) ... 构造。
返回值 指向从 args 构造并插入到 v 的新元素的迭代器。
前置条件 T 原位构造 C ,从 args
v. insert ( p, t ) Iter 效果 p 前插入 t 的副本。
返回值 指向插入到 v t 副本的迭代器。
前置条件

T 复制插入 C

(C++11 起)
v. insert ( p, rv )
(C++11 起)
Iter 效果 p 前插入 rv 的副本,可能使用移动语义。
返回值 指向插入到 v rv 副本的迭代器。
前置条件 T 移动插入 C
v. insert ( p, n, t ) Iter 效果 p 前插入 n t 的副本。
返回值 指向插入到 v 的第一个元素副本的迭代器,或若 n 0 则为 p
前置条件

T

此外,对于每个序列容器:

  • 当对应的模板实参不满足 LegacyInputIterator 要求时,接收两个输入迭代器的构造函数模板以及 insert append assign replace 成员函数模板的重载版本不会参与重载决议。
  • 若推导出的类型不符合输入迭代器或分配器的要求,则带有 LegacyInputIterator Allocator 模板参数的推导指导不会参与重载决议。
(C++17 起)

标准库

以下标准库字符串类型和容器满足 SequenceContainer 要求:

存储和操作字符序列
(类模板)
(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 v. insert ( p, t ) 返回 Iter
v. insert ( p, n, t ) v. insert ( p, n, t )
返回 void
全部返回 Iter
LWG 151 C++98 要求 q1 必须可解引用 [1] 允许不可解引用
LWG 355 C++98 调用 v. back ( ) v. pop_back ( )
执行 -- v. end ( ) ,存在风险 [2]
改为递减 v. end ( ) 的副本
LWG 589 C++98 i j 所引用的元素
可能无法转换为 C::value_type
要求可隐式
转换为 C::value_type
LWG 2194 C++11 std::queue std::priority_queue
std::stack 也被视为 SequenceContainer s [3]
它们不属于 SequenceContainer s
LWG 2231 C++11 v. clear ( ) 的复杂度要求
在 C++11 中被错误遗漏
重新确认复杂度为线性
LWG 3927 C++98 operator [ ] 缺少隐式要求 添加隐式要求
  1. 这是一个缺陷,因为它使得当 v 是空容器时, v. erase ( v. begin ( ) , v. end ( ) ) 的行为变为未定义。
  2. 如果 v. end ( ) 的类型是基本类型, -- v. end ( ) 的格式不正确。当 v 的类型被模板化时尤其危险,这种情况下该缺陷可能难以被发现。
  3. 在 C++98 中它们未被记录为 SequenceContainer