C++ 具名要求:知分配器容器 (AllocatorAwareContainer)

来自cppreference.com
< cpp‎ | named req
 
 
C++ 具名要求
基础
类型属性
库所属
容器
AllocatorAwareContainer

容器元素
迭代器
流 I/O
随机数
并发
(C++11)
(C++11)
其他
 

知分配器容器 (AllocatorAwareContainer) 容器 (Container) ,其保有一个分配器 (Allocator) 实例,并于其所有成员函数中用该实例来分配及解分配内存,并于这个内存中构造及销毁对象的(这种对象可以是容器元素,结点,或对于无序容器为桶数组),除了 std::basic_string 特化不用分配器构造/析构其元素 (C++23 起)

下列规则适用于容器的构造

  • 知分配器容器 (AllocatorAwareContainer) 的复制构造函数,通过在正在复制的容器的分配器上调用 std::allocator_traits<allocator_type>::select_on_container_copy_construction 获得自己的分配器实例。
  • 移动构造函数通过从属于旧容器的分配器进行移动构造,获得其自己的分配器实例。
  • 所有其他构造函数均接收一个 const allocator_type& 形参。

仅有的替换分配器的方式是进行移动赋值、复制赋值及交换:

  • 仅当 std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::valuetrue 时,复制赋值才会替换分配器
  • 仅当 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::valuetrue 时,移动赋值才会替换分配器
  • 仅当 std::allocator_traits<allocator_type>::propagate_on_container_swap::valuetrue 时,交换才会替换分配器。特别是它将通过对非成员函数 swap 的无限定的调用来交换分配器实例,见可交换 (Swappable)

注:若 propagate_on_container_swapfalse,则交换两个拥有不相等分配器的容器是未定义行为。

  • 访问器 get_allocator() 获得构造容器时所用的,或为最近的分配器替换操作所安装的分配器的一个副本。

要求

凡例

X 容器类型
T 元素类型
A T 的分配器
a, b X 类型的对象(非 const 左值)
t X 类型的对象(左值或 const 右值)
rv X 类型的对象(非 const 右值)
m A 类型的对象
Q 分配器类型
表达式 返回类型 前提/要求 后置/效应 复杂度
allocator_type A allocator_type::value_type 必须与 X::value_type 相同 编译时
get_allocator() A 常数
X u; A 可默认构造 (DefaultConstructible) u.empty() == true && u.get_allocator() == A() 常数
X u(m); u.empty() == true && u.get_allocator() == m 常数
X u(t,m); T 可复制插入 (CopyInsertable) X u == t && u.get_allocator() == m 线性
X u(rv); A 的移动构造函数必须不抛异常 u 拥有与 rv 构造前相同的元素和相等的分配器 常数
X u(rv,m); T 可移动插入 (MoveInsertable) X u 的元素与 rv 的相同或是其副本,且 u.get_allocator() == m m == rv.get_allocator() 则为常数,否则为线性
a = t X& T 可复制插入 (CopyInsertable) X可复制赋值 (CopyAssignable) a == t 线性
a = rv X& 若分配器将被移动赋值所替换(见上文),则 T 可移动插入 (MoveInsertable) X可移动赋值 (MoveAssignable) a 的所有既存元素被移动赋值或销毁;若 arv 不指代同一对象则 a 等于 rv 赋值前所拥有的值 线性
a.swap(b) void 交换 ab 的内容 常数

注解

具分配器容器始终调用 std::allocator_traits<A>::construct(m, p, args)p 中用 args 来构造一个 A 类型的对象,其中 m == get_allocator()std::allocator 中默认的 construct 调用 ::new((void*)p) T(args) (C++20 前)std::allocatorconstruct 成员,而在构造元素时 std::construct_at(p, args) 得到调用 (C++20 起),但特化的分配器可以选择不同的定义。

标准库

所有标准库容器,除了 std::array,都是知分配器容器 (AllocatorAwareContainer)

缺陷报告

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

DR 应用于 出版时的行为 正确行为
LWG 2839 C++11 不允许标准容器的自移动赋值 容许但结果未指定