6

The following code won't compile

some_vector.erase(some_vector.rbegin(), some_vector.rbegin()+1);

This is just an example, I know there's better option for deleting the last n elements. GCC tells me that there is no matching function for erase. Did I do something wrong or does erase not work with reverse iterators ? It works fine with a forward iterator, though

Aaa Bbb
  • 627
  • 4
  • 12

1 Answers1

8

It does not. However, reverse iterators provide a base() method to obtain a forward iterator. Take note that the returned forward iterator points to the element following the element the reverse iterator points to.

Or, to put it another way, .rbegin().base() == .end() and .rend().base() == .begin()

So the fixed code would look like this:

some_vector.erase(
    (++(some_vector.rbegin())).base(),
    some_vector.rbegin().base()
);

Note that we have to swap the order of the iterators around since they are reverse iterators; the second argument must be an iterator that follows the first iterator in the sequence, but without swapping the order of the reverse iterators this wouldn't be true. So if we have two reverse iterators a and b, and b >= a then we can use this idiom for erase():

container.erase(b.base(), a.base());

More generally, it holds for the range of reverse iterators [a, b) that the range [b.base(), a.base()) iterates the same sequence of elements in the opposite order.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • Thank you very much, I was unsuccessfully trying to debug my code since 1 week and I never assumed that the base() method was actually returning a off-by-1 iterator... – Aaa Bbb May 18 '17 at 03:13
  • @AaaBbb [This page](http://en.cppreference.com/w/cpp/iterator/reverse_iterator) is an extremely valuable reference for reasoning about reverse iterators. – cdhowie May 18 '17 at 03:14