我有一个模板容器MyContainer<std::unique_ptr<Foo>>
,其中包含std::deque<T>
和std::vector<T>
成员。
内部方法send_to_purgatory_if( predicate )
,如果谓词评估为true,我想查看m_taskdq
中的所有项目并将项目从m_taskdq
移动到m_purgatory
。< / p>
我有两个问题我正在努力:
it
会被删除std::unique_ptr<>
的状态(问题第1行和第2行 - 第2行,我认为{strong> {指向的std::unique_ptr<>
{1}} 未定义?)我该如何修复此代码?
it
答案 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
移出的taskdq
在unique_ptr
之后变为空emplace_back
,然后在下一行中删除。没有伤害,没有犯规。
当存在erase
时,erase
的返回在增加迭代器方面做得很好。当没有erase
时,正常的迭代器增量是有序的。