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?
This post will discuss how to remove the last element from a List in C#. 1. Using List<T>.RemoveAt () Method The RemoveAt () method removes the element present at the specified position in a list. To remove the last element, you can pass the index of it to the RemoveAt () method.
Delete elements in C++ STL list. Using list::erase (): The purpose of this function is to remove the elements from list. Single or multiple contiguous elements in range can be removed using this function. This function takes 2 arguments, start iterator and end iterator. Time complexity : O (n) where (n is size of list).
Pass the index of the element you want to remove as the argument. It modifies the list in place and returns the element removed (or “popped”). To remove the last element from a list, pass the index of the last element in the list (you can also use a negative index, -1) as an argument to the list pop () function. Here’s an example –
Also, u can't delete element from list by value, without iterating it. If you think about it, it doesn't even make sense, because pointers inside the list have to be updated. remove actually removes in this case. This wont compile as it returns void due to that.
I suppose that you can simplify your code snippet doing it the next way:
while (!mylist.empty() && mylist.back()->Type() == unwanted) {
mylist.pop_back();
}
To fix the specific error in your code Can I convert a reverse iterator to a forward iterator?
mylist.erase((pos+1).base());
Using std::reverse_iterator::base
The
base
iterator refers to the element that is next (from thestd::reverse_iterator::iterator_type
perspective) to the element thereverse_iterator
is currently pointing to.
Anyway, pop_back
is the best choice in your case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With