C++ 具名要求:容器 (Container)

来自cppreference.com
< cpp‎ | named req


 
 
C++ 具名要求
 

容器 (Container) 是用于存储其他对象并负责管理那些对象使用的内存的对象。

要求

给定以下类型和值:

类型定义
T对象类型
C包含 T 类型对象的容器类
定义
u, vCconst C 类型的值
mvC 类型的值
cvconst C 类型的值
lhsrhsC 类型的左值
ijC::iteratorconst C::iterator 类型的值

C 在以下类型,语句和表达式都良构并具有指定的语义时满足容器 (Container)

类型

类型定义要求
typename C::value_typeTT 可复制构造 (CopyConstructible) (C++11 前)C 可擦除 (Erasable) (C++11 起)
typename C::referenceT&无显式要求
typename C::const_referenceconst 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. 如果 vC 类型右值,并且 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 = vC&后条件
  • 如果 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 == vbool效果返回
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. 如果 vC 类型右值,并且 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 == ji != ji < ji <= ji >= ji > ji - j 中,如果 i 和/或 j 分别被替换为指向相同元素的 C::const_iterator 类型迭代器,那么语义保持不变。

容器数据竞争

容器线程安全

缺陷报告

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

缺陷报告应用于出版时的行为正确行为
LWG 179C++98iteratorconst_iterator 类型可能不可比较要求可比较
LWG 276C++98T 要求 可复制赋值 (CopyAssignable) T 要求 可复制构造 (CopyConstructible)
LWG 322C++98未指定 iteratorconst_iterator 的值类型指定为 T
LWG 774C++98swap(a, b) 没有要求已补充
LWG 883C++98a.swap(b) 被定义为 swap(a, b),导致循环定义定义为交换 ab 的值
LWG 1319C++98iteratorconst_iterator 不一定有多趟保证它们需要满足
老式向前迭代器 (LegacyForwardIterator)
LWG 2114
(P2167R3)
C++98曾允许某些函数的非 bool 返回类型已禁止
LWG 2182C++98referenceconst_reference 表示的类型未被良好指定改进用词
LWG 2257C++98两个容器即使大小不同也需要线性时间比较相等此时只需要常数时间
LWG 2263C++11LWG 问题 179 的解决方案在 C++11 中被意外丢弃已恢复
LWG 2839C++11不允许标准容器的自移动赋值容许但结果未指定
N3346C++11C::value_type 要求可析构 (Destructible) 要求从 C 可擦除 (Erasable)

参阅

容器库C++ 文档