2

On that page, it's said that:

this invalidates all iterator and references to elements after position or first.

Does that means position and first iterators are valid after the erase?

(Obviously, I ask that because I want to delete some item in a vector during a for_each loop.)

Thank you.

5 Answers 5

2

According to http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#414 positon and first should be considered invalid - the wording in the standard is unclear but as iterators and references are mentioned in one sentence, and a reference to an erased element doesn't make sense, it was "taken for granted" that erasing invalidated iterators pointing to the erased element. I'd avoid depending on the erased iterator being valid - when you erase begin() from a vector with one element I wouldn't take for granted that the iterator suddenly was equal to end()

Sign up to request clarification or add additional context in comments.

2 Comments

" The standard specifically says: "Invalidates all the iterators and references after the point of the erase." This has been raised as a defect. The N3242 draft of C++0x changes this to: "Invalidates iterators and references at or after the point of the erase." – Jerry Coffin.
@Jerry Coffin So I see. It's rather obviously a defect, however, because the definition of not invalidating an iterator means that it points to the same element it did previously. Which is impossible if the element has been removed.
2

Often if you're trying to delete multiple items from a vector in a loop, using remove_if will give you better performance than using erase on each item. Consider this rather than iterate-erase.

To answer your question however, yes they're valid but be careful about incrementing the iterator before testing it for end again, since the erase could make your iterator now equal to end. EDIT: @Erik's answer indicates that it may not actually be valid, but the wording is unclear.

1 Comment

Performance are not (yet) an issue, and I am not enough familiar with the stl to write nice code with the algorithms.
0

Yes. But they won't refer to the same element as they did before the erase(), because that element will have been erased!

Comments

0

If you are erasing while iterating, consider this syntax:

vector<int> items = ...; for(vector<int>::iterator it = items.begin() ; it != items.end() ; /*inline*/) { if(/* should erase*/) it = items.erase(it); else ++it; } 

This works because erase() returns an iterator to the next element after the current one. So, if you erased, it gets 'incremented', otherwise, you increment it like normal. As others have noted though, this is not very efficient (since all elements after the current one are copied forward), and there are better ways. For example, as Mark B mentioned, it may be better to use remove_if.

Comments

0

That's what it says, but it's wrong. According to the standard, they are invalidated (which makes sense, since to remain valid, they'd have to point to an element which was no longer there).

2 Comments

Actually, no. The standard specifically says: "Invalidates all the iterators and references after the point of the erase." This has been raised as a defect. The N3242 draft of C++0x changes this to: "Invalidates iterators and references at or after the point of the erase."
Very useful comment Jerry Coffin.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.