通过反向迭代器从矢量快速删除
fast deletion from vector with a reverse iterator
我想删除符合某些条件的向量入口,呼叫它们的函数。我不在乎稳定的订购,所以通常我实际上会移动最终数组元素来替换正在检查的元素。
问题:用迭代器做到这一点的最光滑的习语是什么?
(是的,如果您想保留订购,则擦除是标准的成语,但是就我而言,这是不需要的,我认为由于这些动作而比我在这里给出的版本要慢。(
(使用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循环的 中吹来。我不知道为什么。如果实际上是在 *上调用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++;
pop_back
通常只应仅使back()
和end()
无效。但是,如果必须删除数组的最后一个元素,则可以被角案抓住。对于索引,没问题,您会尝试在本身上移动一个元素,这应该是一个no-op,然后在先前的索引上进行。但是使用迭代器,当前值是back()
,因此应无效。
提防,这在您的实施中也可能是一个问题,因此提供该信息可能是有意义的,以便其他人可以尝试使用此或其他实现来复制。
我认为旧且经过测试的擦除式成语很好地覆盖了。
apc.erase(std::remove_if(apc.begin(), apc.end(), [](auto& v) {
if (v->blah) {
MyFunc(v);
return true;
}
return false;
}), apc.end());
这个习语将所有要删除的元素移至std::remove_if
的末端,然后我们将所有元素与erase
一起删除。
编辑:正如马歇尔指出的那样,该算法将将要保持在正面的元素将其移动到前面,这是有意义的,考虑到它承诺保留保留元素的相对排序。p>如果lambda需要在this
或其他任何变量上作用,则需要捕获v
中传递的。在这种情况下,我们不必担心寿命,因此默认捕获是一个不错的选择。
[&](auto& v) {
if (v->blah < x) { //captures x by reference
MyFunc(v, member_variable); //current object is captured by reference, and can access member variables
return true;
}
return false;
})
如果MyFunc
可能可以修改member_variable
,我们还需要使Lambda可变。
默认情况下,lambda使用operator() const
创建一个功能对象,但mutable
删除了const
。
[&](auto& v) mutable { ... }
- 使用迭代器 C++ 删除矢量中的重叠字符串
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 如何使用擦除和迭代器来删除二维向量中的项目
- 如果我有一个指向矢量元素的指针,而不是迭代器,如何删除它?
- c++ 在循环中删除迭代器(映射的映射)
- 从矢量C++中删除时,矢量迭代器不可取消引用
- 为什么擦除-删除成语不适用于反向迭代器
- 通过反向迭代器从矢量快速删除
- debug断言矢量迭代器不可用find_if删除
- 如何在不使用循环或迭代器的情况下检查所有列表元素并在满足条件时删除一个
- 如何在给定迭代器列表的情况下从向量中删除元素
- 射击时从列表中删除外星人 - 找出循环;"表达式:无法递增结束列表迭代器"
- 使用迭代器指针 (C++) 从对象指针列表中删除元素
- 为什么删除字符串迭代器会产生const char参考
- 迭代器:如果 '*' 返回元素的引用,为什么删除 *(myList.end()) 会给出 SegFault
- 在迭代器时从 std::list 中删除条目
- 如何使用反向迭代器从“std::set”中删除元素
- C++:从映射中删除迭代器,然后递增到下一个迭代器
- erase删除迭代器所指向的元素失败时的处理方法
- c++不需要删除迭代器