如何实现分配器感知的容器分配
How is allocator-aware container assignment implemented?
例如,来自 std :: Deque :: operator = in C 参考:
(1)复制分配(const std :: Deque& other)
用其他内容的副本代替了内容。
如果 std :: allocator_traits :: propagate_on_container_copy_assignment()是 没错,目标分配器被源的副本替换 分配器。如果目标和源分配器未比较 相等,目标(*此)分配器用于处理内存, 然后,其他分配器用于在复制之前分配 元素。
如果this->get_allocator() == other.get_allocator()
,如果需要的话,我可以简单地销毁和交易 this
'元素,或在需要时分配和构造元素,或在需要时复制从 other
到 *this
的元素。
但是如果没有怎么办?上面的报价是否意味着我不能复制元素,因此我必须首先使用this->get_allocator()
销毁和处理所有元素,然后使用other.get_allocator()
?
分配和构造元素但是,如果是这样,为什么我要使用other.get_allocator()
进行分配?
稍后不会导致某些运行时错误,因为this
无法正确处理内存?
(2)移动分配
(std :: Deque&&&&&&&&strong>
用其他内容代替内容 使用移动语义(即,另一个数据从其他数据移动到 这个容器)。其他人之后处于有效但未指定的状态。 如果 std :: allocator_traits :: propagate_on_container_move_assignment() 是的,目标分配器被源的副本替换 分配器。如果是错误的,并且源和目标分配器确实 不能比较平等,目标不能占有来源 内存,必须单独移动每个元素,分配 根据需要,使用自己的分配器进行其他内存。无论如何,所有人 *最初存在 *中存在的元素要么被破坏或更换 通过ElementWise Move-Assignment。
如果this->get_allocator() == other.get_allocator()
,这是一件容易的任务。
但是,如果不是,则以上相同的问题如下,除非在这种情况下使用移动分配。
在这两种情况下,我都有一个其他问题。
如果这些元素既不能被复制分配或移动分配,可以将其销毁并与其他元素构造吗?如果是这样,我应该使用谁的分配器?
pocca(在container-copy-copy-appy-appy-Assignment)分配器被复制分配为容器的副本分配。同样,当容器的移动分配时,POCMA分配器也会移动。
上面的报价是否意味着我不能复制元素,因此我必须首先使用
this->get_allocator()
销毁和处理所有元素,然后使用other.get_allocator()
分配和构造元素?
正确。
但是,如果是这样,为什么我应该使用
other.get_allocator
进行分配?稍后不会导致某些运行时错误,因为this->get_allocator()
无法正确处理内存?
由于分配传播分配器:分配后,this->get_allocator()
是other.get_allocator()
的副本,因此它可以安全地处理由其分配的内存。
如果
this->get_allocator() == other.get_allocator()
,这是一件容易的任务。但是,如果不是,则以上相同的问题如下,除非在这种情况下使用移动分配。
实际上,这是完全不同的。使用POCMA分配器移动分配是微不足道的:您可以销毁*this
中的所有元素,释放内存,并掠夺other
的内存和分配。
容器移动分配必须诉诸于元素移动分配/构建的唯一情况是,当您具有 non-pocma 分配器和分配器比较不平等时。在这种情况下,所有分配和构造都是用this->get_allocator()
完成的,因为您没有传播任何东西。
在这两种情况下,我都有一个其他问题。如果这些元素既不能被复制分配或移动分配,可以将其销毁并与其他元素构造吗?如果是,我应该使用谁的分配?
使用最初构建的分配器将其销毁;使用分配器构建它将被破坏。换句话说,如果您要传播分配器,请用目标分配器将其销毁并用源分配器构造。
我正在回答自己的问题,以显示我得到了什么。-Dannyu ndos,2017年1月16日
在副本或移动分配中,其行为取决于两个条件:
1。分配器比较相等吗?(也就是说,源分配器能够破坏和处理目标容器的元素吗?)
2。在容器分配过程中,源的分配器的分配器是否传播(=分配给目标)?
用于副本分配:
A。如果分配器比较相等:
可以安全地完成将元素直接复制分配元素。
由于分配器已经比较平等,因此分配器是否传播都无关紧要。如果需要构造或破坏任何元素,那也无关紧要。
b。如果分配器不相等:
B.A。如果分配器不传播:
可以安全地完成直接复制元素到元素,但是如果需要构造或破坏任何元素,则源分配器必须这样做,因为只有它才能破坏目标容器的元素。
b.b。如果分配器传播:
首先,目标分配器必须贫穷并处理所有目标容器的元素。
然后分配器繁殖,然后源分配器分配和复制构造所有源容器的元素。
移动分配:
A。如果分配器比较相等:
目标容器删除其所有元素,然后占据源容器元素的所有权。这需要O(1)时间。
b。如果分配器不相等:
B.A。如果分配器不传播:
可以安全地完成将元素分配到元素上,但是如果需要构造或破坏任何元素,则源分配器必须这样做,因为只有它才能破坏源容器的元素。这需要O(n)时间。源容器必须在分配后处于有效状态。
b.b。如果分配器传播:
首先,目标分配器必须贫穷并处理所有目标容器的元素。
然后分配器繁殖,然后源分配器分配并移动构造所有源容器的元素。这需要O(n)时间。分配后,源容器必须处于有效状态。
在源代码中,给定alloc
是容器的分配器,Alloc
是它的类型,它们通常像这样写:
/*container*/ &operator = (const /*container*/ &other) {
if (std::allocator_traits<Alloc>::propagate_on_container_copy_assignment::value && alloc != other.alloc) {
clear();
alloc = other.alloc;
// directly copy-constructs the elements.
} else {
// directly copy-assigns the elements.
// alloc does all allocation, construction, destruction, and deallocation as needed.
}
return *this;
}
/*container*/ &operator = (/*container*/ &&other)
noexcept(std::allocator_traits<Alloc>::is_always_equal::value) {
if (alloc == other.alloc) {
clear();
// *this takes ownership of other's elements.
} else if (std::allocator_traits<Alloc>::propagate_on_container_move_assignment::value) {
clear();
alloc = other.alloc;
// directly move-constructs the elements.
} else {
// directly move-assigns the elements.
// alloc does all allocation, construction, destruction, and deallocation as needed.
}
// the source container is made valid, if needed.
return *this;
}
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 如何实现分配器感知的容器分配
- 智能感知:不能将 "void" 类型的值分配给类型 "double" 的实体
- 1 智能感知:不能将 "StatementTable::StatementFunc" 类型的值分配给类型 "StatementTable::StatementState" 的实体
- 我如何创建一个多层感知机以下DOD?或者如何存储动态分配的数组
- 智能感知:不能将 "IDeviceServer *" 类型的值分配给类型 "IDeviceServer *" 的实体