vacuumhead vacuumhead - 8 months ago 48
C++ Question

Efficiently remove last element from std::list

This seems like a simple problem, and it is certainly doable, but I'd like to do it efficiently.

The Objective:

Remove the last element from a std::list if it meets a condition.

The Problem:

My compiler (MSVC++ 10) is unhappy about casting a reverse iterator to a const iterator for a method call to std::list.erase(). The message is:

error C2664: 'std::_List_iterator<_Mylist>
std::list<_Ty>::erase(std::_List_const_iterator<_Mylist>)' : cannot
convert parameter 1 from 'std::reverse_iterator<_RanIt>' to

The Code I Tried:

std::list<mytype> mylist;

// lots of code omitted for clarity
bool ends_badly = true;

while(ends_badly && mylist.size() > 0)
auto pos = mylist.crbegin(); // Last element in the list
if ((*pos)->Type() == unwanted)
mylist.erase(pos); // Here is where the compiler complains
ends_badly = false;

I can get around this by using forward iterators and looping through the list to the end, but that's so cumbersome. The compiler is OK with a forward iterator in this context, and I tried casting a the reverse iterator to a const iterator but the compiler didn't like that either.

Erasing a list element from a bidirectional list using a reverse iterator seems like a reasonable thing. Is there something obvious I'm missing here?


I suppose that you can simplify your code snippet doing it the next way:

while (!mylist.empty() && mylist.back()->Type() == unwanted) {