开发者

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

开发者 https://www.devze.com 2023-02-02 19:48 出处:网络
std::vector::erase() does not accept reverse iterator. Is there any way to call this method with a reverse iterator?

std::vector::erase() does not accept reverse iterator.

Is there any way to call this method with a reverse iterator?

My sam开发者_C百科ple 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?


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


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;
}


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


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());


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号