Does vector::erase not work with reverse iterators?
Asked Answered
A

1

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

Alleviator answered 18/5, 2017 at 2:50 Comment(0)
H
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.

Headstall answered 18/5, 2017 at 2:58 Comment(2)
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...Alleviator
@AaaBbb This page is an extremely valuable reference for reasoning about reverse iterators.Headstall

© 2022 - 2024 — McMap. All rights reserved.