Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ set iterator removal

Tags:

c++

set

stl

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;
    }
}
like image 606
Marc Andreson Avatar asked Apr 05 '12 18:04

Marc Andreson


2 Answers

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

like image 71
Alok Save Avatar answered Oct 27 '22 06:10

Alok Save


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.

like image 45
Jerry Coffin Avatar answered Oct 27 '22 08:10

Jerry Coffin