我想在对它们调用函数后删除满足某些条件的 vector 条目。我不关心稳定的顺序,所以实际上我通常会移动最后一个数组元素来替换我正在检查的元素。
问题:使用迭代器执行此操作最巧妙的习惯用法是什么?
(是的,如果您想保留顺序,删除-删除是标准习惯用法,但在我的情况下不需要它,而且我认为由于这些移动,它会比我在这里给出的版本慢。)
使用 int 下标我会这样做,并且这段代码有效:
for ( int i = (int) apc.size() - 1; i >= 0; i-- )
if ( apc[i]->blah ) {
MyFunc( apc[i] );
apc[i] = apc.back();
apc.pop_back();
}
我对反向迭代器进行了同样的尝试,它在第一次进入 if block 后在 for 循环的++ 中爆炸。我不知道为什么。如果实际上在 *it 上调用 erase() 我知道这会使它未定义,但我没有那样做。我想 pop_back() 会取消定义 rbegin()。我应该检查它是否在第一次迭代时进入 if block ,以及它是否仅在那种情况下崩溃。
for ( auto it = apc.rbegin(); it != apc.rend(); it++ )
if ( (*it)->blah ) {
MyFunc( *it );
*it = apc.back();
apc.pop_back();
}
使用前向迭代器它似乎可以工作,但我不喜欢在查找 blah true 元素时让循环停止的断断续续的效果。反向循环有点难看,但至少它是一个真正的循环,而不是这种像半人马一样的半循环半同时混合:
for ( auto it = apc.begin(); it != apc.end(); )
if ( (*it)->blah ) {
MyFunc( *it );
*it = apc.back();
apc.pop_back();
} else
it++;
最佳答案
pop_back
通常只会使 back()
和 end()
无效。但是如果必须删除数组的最后一个元素,您可能会遇到极端情况。使用索引,没问题,您尝试在其自身上移动一个元素,这应该是一个空操作,然后继续上一个索引。但是对于迭代器,当前值是 back()
所以它应该是无效的。
请注意,这也可能是您的实现中的问题,因此提供该信息以便其他人可以尝试使用此实现或其他实现进行重现可能是有意义的。
关于c++ - 使用反向迭代器从 vector 中快速删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56197216/