我有一个模板容器MyContainer<std::unique_ptr<Foo>>,它有一个std::deque<T>和一个std::vector<T>成员.
在内部方法中,如果谓词的计算结果为true send_to_purgatory_if( predicate ),我想查看所有项目m_taskdq并将项目移动到.m_taskdqm_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;
};
Run Code Online (Sandbox Code Playgroud)
How*_*ant 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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在很容易使它与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;
}
}
Run Code Online (Sandbox Code Playgroud)
在unique_ptr从移动taskdq成为空unique_ptr后emplace_back,然后它就会在下一行删除.没有伤害,没有犯规.
当有一个时erase,返回erase就可以很好地增加迭代器.当没有时erase,正常的迭代器增量是有序的.
| 归档时间: |
|
| 查看次数: |
2907 次 |
| 最近记录: |