Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call erase with a reverse iterator using a for loop

Tags:

c++

c++11

Regarding the answer provided here: How to call erase with a reverse iterator

The following results in a segmentation fault (upon ++it) when compiled in g++ 4.8.4 with -std=c++11. Am I misunderstanding the answer?

  std::map<int,int> testmap;
  testmap[0] = 1;
  for(auto it=testmap.rbegin(); it!=testmap.rend(); ++it) {
    testmap.erase( std::next(it).base() );
  }
like image 438
logidelic Avatar asked May 03 '16 13:05

logidelic


People also ask

How do you use reverse iterator?

C++ Iterators Reverse Iterators A reverse iterator is made from a bidirectional, or random access iterator which it keeps as a member which can be accessed through base() . To iterate backwards use rbegin() and rend() as the iterators for the end of the collection, and the start of the collection respectively.

How do I iterate set in reverse order?

Approach: To traverse a Set in reverse order, a reverse_iterator can be declared on it and it can be used to traverse the set from the last element to the first element with the help of rbegin() and rend() functions. Get the set.

How do you iterate through a reverse vector?

So, to iterate over a vector in reverse direction, we can use the reverse_iterator to iterate from end to start. vector provides two functions which returns a reverse_iterator i.e. vector::rend() –> Returns a reverse iterator that points to the virtual element before the start of vector.


1 Answers

erase invalidates iterator, you have to reconstruct it from return of erase:

it = std::map<int,int>::reverse_iterator(testmap.erase( std::next(it).base() ));

or (c++11)

it = decltype(it){testmap.erase( std::next(it).base() )};

Demo.

For completeness, here is what the corrected loop from the original question looks like (notice that the iterator increment has been removed from the for(...):

for (auto rit = testmap.rbegin(); rit != testmap.rend(); /* empty */) {
    if (WE_WANT_TO_ERASE(rit)) {
        rit = decltype(rit){ testmap.erase(std::next(rit).base()) };
    } else {
        ++rit;
    }
}
like image 168
Jarod42 Avatar answered Oct 28 '22 02:10

Jarod42