gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:05:02 25 4
gpt4 key购买 nike

问题

我有一个模板容器 MyContainer<std::unique_ptr<Foo>>它有一个 std::deque<T>和一个 std::vector<T>成员(member)。

内部方法,send_to_purgatory_if( predicate ) , 我想查看 m_taskdq 中的所有项目并从 m_taskdq 移动项目至 m_purgatory ,如果谓词的计算结果为真。

问题

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

  • 我的迭代器 it 如果我从循环内从 m_taskdq 中删除项目,则会被丢弃
  • 我很担心 std::unique_ptr<> 的状态如果我分两步进行移动(问题第 1 行和第 2 行 - 通过第 2 行,我认为 std::unique_ptr<> 指向的 it 未定义?)

我应该如何修复此代码?

    template <typename T>
class MyContainer
{
typedef std::function<bool(T&)> PREDICATE;

void send_to_purgatory_if( PREDICATE p )
{
// bad code -------------------------------------
for( auto it=m_taskdq.begin(); it!=m_taskdq.end(); ++it )
{
if ( p( *it ) )
{
m_purgatory.emplace_back( move( *it )); // problem line 1
m_taskdq.erase( it ); // problem line 2
}
}
// end bad code ---------------------------------
}

std::deque< T > m_taskdq;
std::vector< T > m_purgatory;
};

最佳答案

这实际上是一个 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;
}
}

taskdq中移出的unique_ptremplace_back之后变成了空的unique_ptr,然后被删除在下一行。没有伤害,没有犯规。

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

关于c++ - 如何将 std::unique_ptr<> 从一个 STL 容器移动到另一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9661056/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com