首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >propagate_on_container_move_assignment的示例用法

propagate_on_container_move_assignment的示例用法
EN

Stack Overflow用户
提问于 2014-12-14 15:56:53
回答 1查看 4.8K关注 0票数 23

我正在努力理解如何正确地编写AllocatorAware容器。

我的理解是,当容器本身被移动分配时,propagate_on_container_move_assignment类型指示是否需要复制特定的Allocator类型。

因此,由于我找不到这方面的任何例子,我自己的尝试如下所示:

给定容器类型ContainerAllocator类型allocator_type和内部allocator_type数据成员m_alloc

代码语言:javascript
复制
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容器的复制构造函数是否也需要检查这些类型?我认为答案是肯定的.意思是,我还需要写:

代码语言:javascript
复制
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
         );
      }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-14 18:23:04

我建议研究libc++libc++头。您必须处理所有需要使用的讨厌的下划线std::lib实现者。但是libc++有一个与C++11相一致的实现,用于检查.

移动赋值算子

集装箱移动作业人员必须处理三种不同的可能性:

  1. propagate_on_container_move_assignment是真的。
  2. propagate_on_container_move_assignment是假的,来自lhs和rhs的分配器比较相等。
  3. 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容器。你唯一能做的就是:

代码语言:javascript
复制
assign(make_move_iterator(rhs.begin()), make_move_iterator(rhs.end()));

注意,在案例1中,由于算法是在编译时选择的,容器的value_type不必是MoveAssignableMoveInsertable (MoveConstructible)来移动-分配容器。但是在第2种情况下,value_type必须是MoveAssignableMoveInsertable (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,复制分配分配器,否则不会。然后复制元素:

代码语言:javascript
复制
assign(rhs.begin(), rhs.end());
票数 38
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27471053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档