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

Sil*_*ler 8 c++ allocator c++11

在C++ 11 std::allocator_traits模板用来查询一个Allocator,以确定是否propagate_on_copy_assignmentpropagate_on_move_assignmenttrue.这些值会影响Container类型必须实现复制和移动分配的方式.如果std::allocator_traits<Allocator>::propagate_on_move_assignment == true那么Container移动赋值运算符必须使用RHS Container对象中包含的分配器移动分配其内部分配器对象.

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

那么......为什么这些typedef 适用于赋值.为什么我们没有propagate_on_copy_constructpropagate_on_move_construct?如果一个分配器有一些内部状态,那么客户端容器对象不应该知道它,所以它知道它是否应该复制/移动分配器?

How*_*ant 11

在任务中,有两个选择:

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

propagate_on_assign特性控制赋值运算符的选择.

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

  1. 从零开始构造一个分配器.
  2. 从rhs分配器复制/移动.
  3. 从其他来源复制/移动.

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

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

Alloc select_on_container_copy_construction(const Alloc& rhs);
Run Code Online (Sandbox Code Playgroud)

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

对于只想在复制构建期间复制分配器的分配器设计者(选择2),他们不必做任何事情.

想要在容器拷贝构造上构造lhs allocator default的分配器设计者只需要为其分配器编写以下成员函数:

Alloc select_on_container_copy_construction() const {return Alloc{};}
Run Code Online (Sandbox Code Playgroud)

如果他们想到选择3的聪明之处,他们可能会使用与选择1相同的钩子来实现它.

因此,对于复制构建,不需要propagate_on特征,因为select_on_container_copy_construction已经涵盖所有基础.

有关移动构造,请参见N2982第12页的底部:

请注意,没有select_on_container_move_construction() 功能.经过一番考虑后,我们决定按照问题1166,对容器的移动施工操作必须在恒定时间内运行而不是抛出.

事实上,本文及其前面的文章(它引用的文章)是C++ 11分配器设计背后的基本信息的良好来源.本文甚至参考了allocator_propagate_on_copy_construction之前的论文中的一篇文章,后来演变为select_on_container_copy_construction().