hkBattousai
hkBattousai

Reputation: 10911

How do I pass a "const_reverse_iterator" parameter to "std::vector::erase()"?

std::vector::erase() does not accept reverse iterator.
Is there any way to call this method with a reverse iterator?

My sample code is:

std::vector<int> MyVector;
for (int i=0; i<10; i++)
{
    MyVector.push_back(i);
}
// Now suppose that I want to erase the last three elements
int nEraseCount = 0;
for (std::vector<int>::const_reverse_iterator it=MyVector.rbegin();
        it<MyVector.rend(); ++it)
{
    MyVector.erase(it);
    if (++nEraseCount == 3) break;
}

However, this sample code is not working, because it is a reverse iterator and erase() does not take reverse iterator as its argument.

How do I modify this code so that it works?

Upvotes: 3

Views: 6436

Answers (5)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361352

You cannot pass const_iterator or const_reverse_iterator to erase(), as it is readonly iterator!

You should use non-const forward iterator version : std::vector<int>::iterator.

Upvotes: 1

Nim
Nim

Reputation: 33655

Okay you have several options - you are erasing from the end - so you could:

resize()

if (MyVector.size() > 3)
  MyVector.resize(MyVector.size() - 3);
else
  MyVector.clear(); // presumably you don't want all anyway!

simple difference

if (MyVector.size() > 3)
  MyVector.erase(MyVector.end() - 3, MyVector.end());
else
  MyVector.clear(); // presumably you don't want all anyway!

The approach you've taken is not very idiomatic

Upvotes: 4

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136238

If you just want to remove N elements at the back:

size_t N = 3;
size_t to_remove = std::min(vec.size(), N);
vec.erase(vec.end() - to_remove, vec.end());

Upvotes: 3

Sylvain Defresne
Sylvain Defresne

Reputation: 44493

I would workaround the problem by not using a reverse iterator. I'll probably write something like that:

std::vector<int> MyVector;
for (int i=0; i<10; i++)
{
    MyVector.push_back(i);
}
// Now suppose that I want to erase the last three elements
int nEraseCount = 0;
while (nEraseCount < 3 && !MyVector.empty())
{
    MyVector.pop_back();
    ++nEraseCount;
}

Upvotes: 5

CashCow
CashCow

Reputation: 31435

You can convert from reverse_iterators to iterators using base() although you need to subtract one to get the one that points to the same element thus rbegin() points to end() and rend() points to begin() (because it is not possible to point to one before the beginning in reality).

You have more of a problem because you are using a const_reverse_iterator which cannot be converted to a non-const one and erase requires non-const iterators. The logic is that you are modifying the collection so you use a non-const iterator.

In your case, you have a bigger problem with your loop as you are removing iterators thus invalidating them, then trying to move back to the previous element.

If you need to remove the last 3 elements then you should use an erase method that takes a range rather than remove them one at a time.

This can be done using MyVector.erase(MyVector.rbegin() + 3).base(), MyVector.end() ) in this particular case as long as you know that MyVector.size() >= 3

Upvotes: 7

Related Questions