我正在努力理解如何正确地编写AllocatorAware容器。
我的理解是,当容器本身被移动分配时,propagate_on_container_move_assignment类型指示是否需要复制特定的Allocator类型。
因此,由于我找不到这方面的任何例子,我自己的尝试如下所示:
给定容器类型Container、Allocator类型allocator_type和内部allocator_type数据成员m_alloc。
Container& operator = (Container&& other)
{
if (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
{
m_alloc = std::allocator_traits<allocator_type>::select_on_container_copy_construction(
other.m_alloc
);
}
return *this;
}这是正确的吗?
另外,这里的另一个原因是嵌套类型propagate_on_container_move/copy_assignment专门讨论赋值.但是建筑工人呢?移动构造函数或AllocatorAware容器的复制构造函数是否也需要检查这些类型?我认为答案是肯定的.意思是,我还需要写:
Container(Container&& other)
{
if (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
{
m_alloc = std::allocator_traits<allocator_type>::select_on_container_copy_construction(
other.m_alloc
);
}
}发布于 2014-12-14 18:23:04
我建议研究libc++的libc++头。您必须处理所有需要使用的讨厌的下划线std::lib实现者。但是libc++有一个与C++11相一致的实现,用于检查.
移动赋值算子
集装箱移动作业人员必须处理三种不同的可能性:
propagate_on_container_move_assignment是真的。propagate_on_container_move_assignment是假的,来自lhs和rhs的分配器比较相等。propagate_on_container_move_assignment是假的,来自lhs和rhs的分配器比较不相等。在可能的情况下,这三种情况之间的决定应该在编译时作出,而不是在运行时。具体来说,应该在编译时在集合{1}和{2,3}之间进行选择,因为propagate_on_container_move_assignment是编译时间常数。编译时常量上的编译时分支通常是用标签调度完成的,而不是如您所示的if-语句。
在这些情况下,都不应该使用select_on_container_copy_construction。该函数仅用于容器复制构造函数。
在情况1中,lhs应该首先使用lhs的分配程序来释放已分配的所有内存。这必须首先执行,因为rhs分配程序以后可能无法释放此内存。然后lhs分配器是从rhs分配器(就像任何其他移动分配一样)中移动分配的。然后,将存储器所有权从rhs容器转移到lhs容器。如果容器的设计不能使rhs容器处于无资源状态(设计很差),那么rhs容器的rhs分配程序可以为rhs容器分配新的资源。
如果propagate_on_container_move_assignment为false,则必须在运行时在第2和第3种情况之间进行选择,因为分配程序比较是运行时操作。
在第2种情况下,您可以执行与案例1相同的操作,但不要移动分配器。跳过那一步。
在第3种情况下,不能将任何内存的所有权从rhs容器转移到lhs容器。你唯一能做的就是:
assign(make_move_iterator(rhs.begin()), make_move_iterator(rhs.end()));注意,在案例1中,由于算法是在编译时选择的,容器的value_type不必是MoveAssignable或MoveInsertable (MoveConstructible)来移动-分配容器。但是在第2种情况下,value_type必须是MoveAssignable和MoveInsertable (MoveConstructible),尽管它们从来都不是,因为您在运行时选择2到3。3需要在value_type上进行这些操作来执行assign。
移动赋值算子很容易成为集装箱中最复杂的特殊成员。其余的要容易得多:
移动构造函数
move构造函数只需移动构造分配器,并从rhs中窃取资源。
复制构造函数
复制构造函数从select_on_container_copy_construction(rhs.m_alloc)获取其分配器,然后使用它为副本分配资源。
拷贝赋值算子
复制赋值操作符必须首先检查propagate_on_container_copy_assignment是否为真。如果是的话,如果lhs和rhs分配器比较不相等,那么lhs必须首先释放所有内存,因为在分配器被拷贝分配之后,lhs不能这样做。接下来,如果propagate_on_container_copy_assignment,复制分配分配器,否则不会。然后复制元素:
assign(rhs.begin(), rhs.end());https://stackoverflow.com/questions/27471053
复制相似问题