Reputation: 2774
Is it possible to iterate in one single step through elements of a vector, while deleting some of the elements, to prevent repeated processing? (I know the fragment is bogus, but illustrates what I want)
std::vector<MyRecord*>* BLV = GetVector();
for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end(); ++it)
{
MyRecord* BL = *it;
if(Selected)
{
delete BL;
BLV->erase(it);
}
}
Upvotes: 2
Views: 1165
Reputation: 21156
songyuanyao already gave you a nice answer: In short, you have to reset your iterator to the value returned by erase
.
However, if applicable, I'd suggest using a vector of unique_ptr's and the erase-remove idiom (which is also more efficient, as it only moves the elements once).
std::vector<std::unique_ptr<MyRecord>>* BLV = GetVector();
BLV->erase(
std::remove_if(BLV->begin(), BLV->end(),
[&](const std::unique_ptr<MyRecord>& rec) { return Selected; }
),
BLV->end()
);
Upvotes: 1
Reputation: 172924
Note std::vector::erase
will invalidate the iterator to the element to be erased, and then ++it;
will lead to UB.
Invalidates iterators and references at or after the point of the erase, including the end() iterator.
You can use the return value of erase()
.
Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned.
then change the loop to
for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end(); )
{
MyRecord* BL = *it;
if(Selected)
{
delete BL;
it = BLV->erase(it);
} else
{
++it;
}
}
Upvotes: 8