This is really a C ++ 98 question with a red herring regarding the semantics of movement. The first thing to ask is to do it in C ++ 98:
std::deque::erase(iterator) returns an iterator that refers to the element after erasing. So first get started:
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; } }
And now it's easy to get it working with the C ++ 11 relocation semantics:
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 moved from taskdq becomes unique_ptr null after emplace_back , and then erased in the next line. No harm, no foul.
When there is an erase , returning from erase does a good job of increasing the iterator. And when there is no erase , the normal increment of the iterator is in order.
source share