Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erasing element from a vector – rbegin() vs begin() [duplicate]

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;
}
like image 745
RedHelmet Avatar asked Dec 05 '19 18:12

RedHelmet


1 Answers

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();
like image 145
ネロク・ゴ Avatar answered Nov 06 '22 10:11

ネロク・ゴ