Marc Andreson
Marc Andreson

Reputation: 3495

C++ set iterator removal

Is it allowed to erase an element pointed by iterator, and advance the same iterator in one line to go to next element?

set<int>::iterator it = S.begin();
while (it != S.end()) {
    if (shouldBeRemoved(*it)) {
        S.erase(it++); // is this line valid?
    } else {
        ++it;
    }
}

Upvotes: 9

Views: 839

Answers (2)

Alok Save
Alok Save

Reputation: 206518

Is it allowed to erase an element pointed by iterator, and advance the same iterator in one line to go to next element?

Yes, it is valid.


Rationale:

it++ increments it so that it refers to the next element but yields a copy of its original value. Thus, it doesn't refer to the element that is removed when erase() is called. And in case of std::set only iterators to the erased element are invalidated.#1

You can consider this code example as a boilerplate code to remove an element to which your iterator is referring.


References:

For std::set,
#1C++03 Standard 23.1.2/8:

Only iterators and references to the erased elements are invalidated

Upvotes: 5

Jerry Coffin
Jerry Coffin

Reputation: 490108

Yes, it's valid. The expression it++ is fully evaluated before the function is called, so the function receives the previous value of it, but by the time that gets removed (and invalidated), the iterator has already been incremented.

Upvotes: 2

Related Questions