11

I'm trying to solve a problem in C++, a part of which requires me to erase elements from a vector using the rbegin() member function. However, the compiler throws an error every time I write the below-mentioned code. What's wrong here?

int main() {

    int a = 1, b = 2;

    vector<int> V = {a, b};

    auto it = V.rbegin();
    V.erase(it);

    return 0;
}

ERROR:

It compiles just fine, however, if I access the same element using the begin() member function. The code below works fine.

int main() {

    int a = 1, b = 2;

    vector<int> V = {a, b};

    auto it = V.begin()+1;
    V.erase(it);

    return 0;
}
JFMR
  • 23,265
  • 4
  • 52
  • 76
RedHelmet
  • 213
  • 1
  • 7
  • 4
    What is the error you receive? It should explain the issue immediately. Specifically, I don't believe there is a `vector::erase` overload that accepts a `reverse_iterator` - only one that accepts an `iterator`. – user11923373 Dec 05 '19 at 18:49
  • 1
    Have a look [here](https://en.cppreference.com/w/cpp/container/vector/erase). You will see that `erase` only accepts `const_iterator` since c++11 – ChrisMM Dec 05 '19 at 18:50
  • 1
    Does this answer your question? [How to call erase with a reverse iterator](https://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator) – Lukas-T Dec 05 '19 at 18:54
  • Thanks Churill. Didn't know this stuff – RedHelmet Dec 05 '19 at 19:02

1 Answers1

11

There is no std::vector::erase() overload for reverse_iterator. However, you can obtain the corresponding iterator from a reverse_iterator by calling its base() member function:

auto rit = V.rbegin();
auto it = rit.base();
V.erase(it);

This code does compile but results in undefined behavior because the iterator counterpart of rbegin() corresponds to end(). From std::vector::erase() documentation:

iterator erase(const_iterator pos);

The iterator pos must be valid and dereferenceable. Thus the end() iterator (which is valid, but is not dereferencable) cannot be used as a value for pos.


rbegin().base() returns end(), not end() - 1. Nevertheless, you can advance rbegin() by one if you want a dereferencable iterator:

auto it = (std::next(rit)).base();
JFMR
  • 23,265
  • 4
  • 52
  • 76