命名空间
变体
操作

C++ 命名要求: 容器

来自 cppreference.cn
< cpp‎ | named req
 
 
C++ 命名要求
 

容器 是用于存储其他对象并负责管理其包含对象所用内存的对象。

目录

[编辑] 要求

给定以下类型和值

类型 定义
T 对象类型
C 包含 T 类型对象的容器类
定义
u, v 类型为 Cconst C 的值
mv 类型为 C 的值
cv 类型为 const C 的值
lhs, rhs 类型为 C 的左值
i, j 类型为 C::iteratorconst C::iterator 的值

如果以下类型、语句和表达式形式良好且具有指定的语义,则 C 满足 容器 的要求

[编辑] 类型

类型 定义 要求
typename C::value_type T TCopyConstructible(直到 C++11)ErasableC(自 C++11 起)
typename C::reference T& 无显式要求
typename C::const_reference const T&
typename C::iterator 迭代器类型
typename C::const_iterator 常量迭代器类型 C::const_iteratorLegacyForwardIterator,并且其 值类型T
typename C::difference_type 有符号整数类型 C::difference_typeC::iteratorC::const_iterator差值类型 相同。
typename C::size_type 无符号整数类型 C::size_type 足够大以表示 C::difference_type 的所有非负值。

[编辑] 语句

语句 语义  复杂度 
C c;

C c = C();

后置条件  c.empty()true 常数
C c(v);

C c = C(v);

先决条件

如果 v 不是类型 C 的右值,则 TCopyInsertableC 中。

(自 C++11 起)
线性[1]
后置条件
  • 如果 v 是左值,则 c == vtrue
  • 如果 v 是右值,并且 cv 不引用同一对象(自 C++11 起),则 c 等于此构造之前 v 所具有的值。
注释
  1. 如果 v 是类型 C 的右值,并且 C 不是 std::arraystd::inplace_vector 的特化,则复杂度为常数。

[编辑] 表达式

表达式 类型 语义  复杂度 
C() C 后置条件  C().empty()true 常数
C(v) C 先决条件

如果 v 不是类型 C 的右值,则 TCopyInsertableC 中。

(自 C++11 起)
常数[1]
后置条件
  • 如果 v 是左值,则 C(v) == vtrue
  • 如果 v 是右值,并且 C(v)v 不引用同一对象(自 C++11 起),则 C(v) 等于此构造之前 v 所具有的值。
lhs = v C& 后置条件
  • 如果 v 是左值,则 lhs == vtrue
  • 如果 v 是右值,并且 lvv 不引用同一对象(自 C++11 起),则 lhs 等于此赋值之前 v 所具有的值。
线性
v.~C() void 效果 销毁 v 的所有元素并释放所有已获得的内存。 线性
mv.begin() C::iterator 效果 返回指向 mv 第一个元素的迭代器。 常数
cv.begin() C::const_iterator 效果 返回指向 cv 第一个元素的迭代器。 常数
mv.end() C::iterator 效果 返回 mv 的超尾迭代器。 常数
cv.end() C::const_iterator 效果 返回 cv 的超尾迭代器。 常数
v.cbegin()
(自 C++11 起)
C::const_iterator 效果 返回 const_cast<const C&>(v).begin() 常数
v.cend()
(自 C++11 起)
C::const_iterator 效果 返回 const_cast<const C&>(v).end() 常数
i <=> j
(自 C++20 起)
std::strong_ordering     约束 只有当 C::iterator 满足随机访问迭代器要求时,此表达式才是必需的形式良好的。 常数
u == v bool 效果 返回值
u.size() == v.size() &&
    std::equal(u.begin(),
         u.end(), v.begin())
(直到 C++14)
std::equal(u.begin(), u.end(),
           v.begin(), v.end())
(自 C++14 起)
.
线性[2]
u != v 效果 等价于 !(u == v)
lhs.swap(rhs)

swap(lhs, rhs)

void 效果 交换 lhsrhs 的内容。 常数[3]
v.size() C::size_type 效果 返回 v 的元素数量。[4] 常数
v.max_size() C::size_type 效果 返回类型为 C 的最大可能容器的元素数量。 常数
v.empty() bool 效果 返回 v.begin() == v.end() 常数
可选容器要求
(仅为某些类型的容器提供)
u <=> v
(自 C++20 起)
synth-three-way-result
    <C::value_type>
先决条件 T 建模 three_way_comparable,或者 operator< 是为类型 Tconst T 的值定义的完全排序关系。 线性
效果 返回 std::lexicographical_compare_three_way
    (u.begin(), u.end(),
     v.begin(), v.end(),
     synth-three-way)
[5]
注释
  1. 如果 v 是类型 C 的右值,并且 Cstd::arraystd::inplace_vector 的特化,则复杂度为线性。
  2. 如果 u.size() != v.size()true,则复杂度为常数。
  3. 如果 Cstd::arraystd::inplace_vector 的特化,则复杂度为线性。
  4. 元素的数量由构造函数、插入和擦除的规则定义。它等于 std::distance(v.begin(), v.end()) 的值。
  5. 如果传递给 std::lexicographical_compare_three_way 的迭代器是 ConstexprIterators,则操作由 constexpr 函数实现。

在表达式 i == ji != ji < ji <= ji >= ji > ji - j 中,如果 i 和/或 j 分别被指向相同元素的 C::const_iterator 类型的迭代器替换,则语义保持不变。

[编辑] 容器数据竞争

参见 容器线程安全

[编辑] 缺陷报告

以下行为变更缺陷报告已追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
LWG 179 C++98 iteratorconst_iterator 类型可能不可比较 要求可比较
LWG 276 C++98 T 需要为 CopyAssignable T 需要为
CopyConstructible
LWG 322 C++98 iteratorconst_iterator 的值类型未指定 指定为 T
LWG 774 C++98 swap(a, b) 没有要求 已添加
LWG 883 C++98 a.swap(b) 定义为 swap(a, b)
导致循环定义
定义为交换
ab 的值
LWG 1319 C++98 iteratorconst_iterator
可能不具有多趟保证
它们需要满足
的要求
LegacyForwardIterator
LWG 2114
(P2167R3)
C++98 允许某些函数使用非 bool 返回类型 不允许
LWG 2182 C++98 reference
const_reference 表示的类型指定不明确
改进措辞
LWG 2257 C++98 两个容器需要线性时间来比较
相等,即使它们具有不同的大小
在这种情况下仅需要常数
时间
LWG 2263 C++11 LWG issue 179 的解决方案在 C++11 中意外丢失 已恢复
LWG 2839 C++11 不允许标准容器的自移动赋值 允许,但
结果未指定
N3346 C++11 C::value_type 需要为 Destructible 需要为 ErasableC

[编辑] 参见

C++ 文档,关于 容器库