C ++ 11 std::allocator_traits
模板用于查询Allocator
以确定propagate_on_copy_assignment
和propagate_on_move_assignment
是true
。这些值会影响Container类型必须实现复制和移动分配的方式。如果std::allocator_traits<Allocator>::propagate_on_move_assignment == true
那么Container移动赋值运算符必须使用RHS Container对象中包含的分配器移动分配其内部分配器对象。
据推测,重点在于我们可以实现Allocator
类型,这些类型可以通知客户端容器move
或copy
操作是否应该要求我们复制任何内部分配器内的状态。
那么......为什么这些typedef 仅适用于赋值。为什么我们没有propagate_on_copy_construct
和propagate_on_move_construct
?如果分配器具有某种内部状态,那么客户端容器对象是否应该知道这一点,以便它知道它是否应该复制/移动分配器?
答案 0 :(得分:9)
在作业中,有两个选择:
propagate_on_assign
traits控制赋值运算符的选择。
对于构造,选择1(保留现有分配器)不是一种选择。那里的没有现有的分配器。相反,您的选择是:
可以考虑选择一个:默认构造一个分配器。选择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()
。