vacuumhead vacuumhead - 1 month ago 6
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
'std::_List_const_iterator<_Mylist>'



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
}
else
{
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?

Answer

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

while (!mylist.empty() && mylist.back()->Type() == unwanted) {
    mylist.pop_back();
}
Comments