【发布时间】:2019-10-05 10:10:09
【问题描述】:
我想在对它们调用函数后删除满足某些条件的向量条目。我不关心稳定的排序,所以实际上我通常会移动最后一个数组元素来替换我正在检查的那个。
问题:使用迭代器执行此操作的最巧妙的习惯用法是什么?
(是的,如果你想保留顺序,erase-remove 是标准的习惯用法,但在我的情况下,它不是必需的,而且我认为由于这些动作,它会比我在此处给出的版本慢。)
使用 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 块后在 for 循环的 ++ 中爆炸。我不知道为什么。如果实际上在 *it 上调用了 erase(),我知道这会导致它未定义,但我没有这样做。我想 pop_back() 会取消定义 rbegin()。我应该检查它是否在第一次迭代时进入 if 块,以及它是否只在这种情况下崩溃。
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++;
【问题讨论】:
-
我会使用
std::remove_if -
看看erase-remove成语。您可以在删除之后和擦除之前调用
MyFunc,或者您可以将对MyFunc的调用烘焙到您传递给remove_if的比较器中。 -
已回复here
标签: c++ vector stl iterator erase