C++ std::erase and rbegin/rend

Once. Only once have I done this.

I had to traverse a std::vector in reverse, and at some point, I had to call std::erase.

I thought, “Ok, this should work” and instead, something bad happened.

I little digging around, and a stackoverflow.com answer later, I saw an answer that left me scratching my head.

The short answer is, if you are using a reverse_iterator, you have to supply an iterator that std::erase can work with. You do that by calling base on the iterator. You also have to move the iterator one position over since reverse_iterators and regular iterators point to different positions… the nature of each type of iterator.

Here’s an example of how to do that:

#include <iostream>
#include <vector>

void print_contents(const std::vector<int>& items);

int main(int, char**)
{
  auto some_numbers = std::vector<int>{1, 2, 3, 4, 5, 6};
  print_contents(some_numbers);

  // Get an iterator to the last item; then increment that for the second to last item iterator
  auto last           = some_numbers.rbegin();
  auto second_to_last = std::next(last);

  // Now convert the second to last iterator to an iterator erase can use
  auto pos = std::next(second_to_last).base();
  some_numbers.erase(pos);
  print_contents(some_numbers);
}

void print_contents(const std::vector<int>& items)
{
  for (const auto& item : items)
    std::cout << item << "\n";
}

Refs:

https://www.cplusplus.com/reference/vector/vector/rbegin/

https://stackoverflow.com/a/1830240

Leave a Reply

Your email address will not be published. Required fields are marked *