例如,从std::deque::运算符 =在 C++ 参考中:
(1)复制分配 (const std::deque 及其他)
将内容替换为其他内容的副本。
如果
std::allocator_traits::propagate_on_container_copy_assignment() 是
true,目标分配器被源分配器的副本替换
分配器。如果目标分配器和源分配器不比较
相等,目标(*this)分配器用于释放内存,
然后在复制之前使用其他分配器来分配它
元素。
If this->get_allocator() == other.get_allocator()
,我可以简单地销毁和释放this
' 如果需要的话元素,或者如果需要的话分配和构造元素,或者复制分配元素other
to *this
如果需要的话。
但如果没有呢?上面的引用是否意味着我无法复制分配元素,所以我必须首先使用来销毁和取消分配所有元素this->get_allocator()
,然后分配并构造元素,使用other.get_allocator()
?
但如果是这样的话,我为什么要使用other.get_allocator()
用于分配?
稍后会不会导致一些运行时错误,如this
不会正确释放内存吗?
(2) 移动分配 (std::双端队列&&其他)
将内容替换为其他内容
使用移动语义(即 other 中的数据从 other 移动到
这个容器)。 other 随后处于有效但未指定的状态。
如果
std::allocator_traits::propagate_on_container_move_assignment()
为 true 时,目标分配器将被源分配器的副本替换
分配器。如果为 false 并且源分配器和目标分配器执行此操作
比较不相等,目标无法获得源的所有权
内存并且必须单独移动分配每个元素,分配
根据需要使用自己的分配器添加额外的内存。无论如何,所有
最初存在于 *this 中的元素被破坏或替换
通过元素移动赋值。
If this->get_allocator() == other.get_allocator()
,这是一个简单的任务。
但如果不是,则会出现上述相同的问题,只不过在这种情况下使用了移动分配。
对于这两种情况,我都有一个额外的问题。
如果元素既不能复制分配也不能移动分配,是否可以销毁它并从其他元素构造?如果是,我应该使用谁的分配器?
POCCA(在容器上复制分配)分配器作为容器复制分配的一部分进行复制分配。同样,当分配容器的移动时,POCMA 分配器也会被移动分配。
上面的引用是否意味着我无法复制分配元素,所以我必须首先使用来销毁和取消分配所有元素this->get_allocator()
,然后分配并构造元素,使用other.get_allocator()
?
Correct.
但如果是这样的话,我为什么要使用other.get_allocator
用于分配?稍后会不会导致一些运行时错误,如this->get_allocator()
不会正确释放内存吗?
因为赋值会传播分配器:赋值后,this->get_allocator()
是一个副本other.get_allocator()
,因此它可以安全地释放它分配的内存。
If this->get_allocator() == other.get_allocator()
,这是一个简单的任务。但如果不是,则会出现上述相同的问题,只不过在这种情况下使用了移动分配。
事实上,这是完全不同的。使用 POCMA 分配器移动分配很简单:您销毁了中的所有元素*this
,释放内存,并掠夺内存和分配器other
.
容器移动分配必须诉诸元素移动分配/构造的唯一情况是当您有一个非POCMA分配器和分配器比较不相等。在这种情况下,所有的分配和构建都是通过this->get_allocator()
因为你不传播任何东西。
对于这两种情况,我都有一个额外的问题。如果元素既不能复制分配也不能移动分配,是否可以销毁它并从其他元素构造?如果是,我应该使用谁的分配器?
使用最初构建它的分配器销毁它;使用它将被销毁的分配器来构造它。换句话说,如果要传播分配器,则使用目标分配器销毁它并使用源分配器构造。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)