如何移动std :: unique_ptr<>从一个STL容器到另一个?

时间:2012-03-12 02:30:35

标签: c++ stl c++11

问题

我有一个模板容器MyContainer<std::unique_ptr<Foo>>,其中包含std::deque<T>std::vector<T>成员。

内部方法send_to_purgatory_if( predicate ),如果谓词评估为true,我想查看m_taskdq中的所有项目并将项目从m_taskdq移动到m_purgatory。< / p>

问题

我有两个问题我正在努力:

    如果我从循环内部删除m_taskdq中的项目
  • 我的迭代器 it 会被删除
  • 如果我分两步执行此操作,我担心std::unique_ptr<>的状态(问题第1行和第2行 - 第2行,我认为{strong> {指向的std::unique_ptr<> {1}} 未定义?)

我该如何修复此代码?

it

1 个答案:

答案 0 :(得分:13)

这实际上是一个C ++ 98问题,带有关于移动语义的红鲱鱼。首先要问的是如何在C ++ 98中执行此操作:

std::deque::erase(iterator)会返回一个iterator,它引用一个被删除后的元素。所以先做好准备:

 void send_to_purgatory_if( PREDICATE p )
  {
    for( auto it=m_taskdq.begin(); it!=m_taskdq.end();)
    {
      if ( p( *it ) )
      {
        m_purgatory.emplace_back(*it);
        it = m_taskdq.erase(it);
      }
      else
        ++it;
    }
  }

现在很容易使它适用于C ++ 11移动语义:

 void send_to_purgatory_if( PREDICATE p )
  {
    for( auto it=m_taskdq.begin(); it!=m_taskdq.end();)
    {
      if ( p( *it ) )
      {
        m_purgatory.emplace_back(std::move(*it));
        it = m_taskdq.erase(it);
      }
      else
        ++it;
    }
  }

unique_ptr移出的taskdqunique_ptr之后变为空emplace_back,然后在下一行中删除。没有伤害,没有犯规。

当存在erase时,erase的返回在增加迭代器方面做得很好。当没有erase时,正常的迭代器增量是有序的。