命名空间
变体
操作

C++ 命名需求: 容器 (Container)

来自 cppreference.cn
 
 
C++ 命名要求
基本
类型属性
全库范围




Container(容器)
Container(容器)
容器元素
迭代器 (Iterator)
流 I/O
格式化器
随机数
并发
范围 (Ranges)
多维视图
其他

 

一个 容器 (Container) 是一个用于存储其他对象并管理其所包含对象所用内存的对象。

目录

[编辑] 要求

给定以下类型和值

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

如果以下类型、语句和表达式是良构的并具有指定语义,则 C 满足 容器 (Container) 的要求

[编辑] 类型

类型 定义 要求
typename C::value_type T T可复制构造的 (CopyConstructible)(C++11 前)可从 C 擦除的 (Erasable)(C++11 起)
typename C::reference T& 无明确要求
typename C::const_reference const T&
typename C::iterator 一个迭代器类型
typename C::const_iterator 一个常迭代器类型 C::const_iterator 是一个 LegacyForwardIterator,其值类型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 的右值,则 T 可复制插入到 (CopyInsertable) C 中。

(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 的右值,则 T 可复制插入到 (CopyInsertable) C 中。

(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 的迭代器是 ConstexprIterator,则该操作由 constexpr 函数实现。

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

[编辑] 容器数据竞争

参见 容器线程安全

[编辑] 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 发布时的行为 正确的行为
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) 被要求 可从 C 擦除的 (Erasable)

[编辑] 另请参见

C++ 文档 关于 容器库