为什么propagate_on_XXX_assignment不适用于构造函数



C++11 std::allocator_traits模板用于查询Allocator以确定propagate_on_copy_assignmentpropagate_on_move_assignment是否true。 这些值会影响容器类型必须实现复制和移动分配的方式。 如果std::allocator_traits<Allocator>::propagate_on_move_assignment == true则容器移动分配操作员必须使用 RHS 容器对象中包含的分配器移动分配其内部分配器对象。

据推测,这样做的要点是,我们可以实现Allocator类型,这些类型可以通知客户端容器movecopy操作是否应该要求我们在分配器中复制任何内部状态。

那么......为什么这些类型定义适用于赋值。 为什么我们没有propagate_on_copy_constructpropagate_on_move_construct? 如果分配器具有某种内部状态,则客户端容器对象是否应该意识到这一点,以便它知道是否应该复制/移动分配器?

在作业中,有两个选择:

  1. 保留现有的分配器。
  2. 从 rhs 分配器复制/移动。

propagate_on_assign特征控制赋值运算符的选择。

对于构造,选择 1(保留现有分配器(不是一个选项。 没有现有的分配器。 相反,您的选择是:

  1. 从无到有构建分配器。
  2. 从 rhs 分配器复制/移动。
  3. 从其他来源复制/移动。

可以考虑选择一种:默认构造一个分配器。 选择 3 非常模糊,但不同的分配器方案可能是不可预测的,最好给分配器设计者尽可能多的灵活性:可能做一些委员会从未预料到的事情。

为了满足所有三个选择,至少对于容器复制构造函数,设计了一个新的allocator_traits"开关":

Alloc select_on_container_copy_construction(const Alloc& rhs);

allocator_traits 将返回rhs. select_on_container_copy_construction()如果该表达式格式正确。 否则它将返回rhs . 容器复制构造函数在复制构造过程中构造 lhs 分配器时需要使用allocator_traits<A>:: select_on_container_copy_construction(a)

对于只想在复制构造期间复制分配器的分配器设计人员(选择 2(,他们不必执行任何操作。

想要在容器复制构造上构造 lhs 分配器默认值的分配器设计器只需要为其分配器编写以下成员函数:

Alloc select_on_container_copy_construction() const {return Alloc{};}

如果他们为选择 3 想到了一些聪明的东西,他们可能会使用与选择 1 相同的钩子来实现它。

因此,对于副本构造,不需要propagate_on特征,因为select_on_container_copy_construction已经涵盖了所有基础。

有关移动结构,请参阅 N12 第 2982 页的底部:

请注意,没有select_on_container_move_construction() 功能。经过一番考虑,我们决定搬家 集装箱的施工操作必须在恒定时间内运行,并且 不抛出,根据问题 1166。

事实上,这篇论文以及它之前的论文(它引用的(是 C++11 分配器设计背后的基本原理的良好信息来源。 本文甚至引用了前一篇论文的allocator_propagate_on_copy_construction,该论文后来演变为select_on_container_copy_construction()

最新更新