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

时间:2014-12-15 20:27:53

标签: c++ c++11 allocator

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?如果分配器具有某种内部状态,那么客户端容器对象是否应该知道这一点,以便它知道它是否应该复制/移动分配器?

1 个答案:

答案 0 :(得分:9)

在作业中,有两个选择:

  1. 保留现有的分配器。
  2. 从rhs分配器复制/移动。
  3. propagate_on_assign traits控制赋值运算符的选择。

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

    1. 从零开始构建一个分配器。
    2. 从rhs分配器复制/移动。
    3. 从其他来源复制/移动。
    4. 可以考虑选择一个:默认构造一个分配器。选择3非常模糊,但不同的分配器方案可能是不可预测的,为分配器设计者提供尽可能多的灵活性是好的:可能做一些委员会从未预料到的事情。

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

      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 allocator default的分配器设计者只需要为其分配器编写以下成员函数:

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

      如果他们想到选择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()