I have a std::list<some_object> events
and I would like to delete all elements of that list except the last one. So I thought of doing (as suggested by this thread):
std::list<some_object>::iterator it = events.begin(); // Init iterator on top of list
while(it!=*std::advance(events.end(),-1)) events.erase(it++);
Unfortunately the above is not working as it produces the error:
error: invalid initialization of non-const reference of type ‘std::_List_iterator<node_info>&’ from an rvalue of type ‘std::__cxx11::list<node_info>::iterator {aka std::_List_iterator<node_info>}’
while(it!=*std::advance(event_heap.end(),-1)){
But, isn't list::end
supposed to return an iterator? What am I doing wrong?
But, isn't list::end supposed to return an iterator?
Yes, but std::advance
takes non-const reference as its 1st parameter, while event_heap.end()
is a temporary variable and can't be bound to non-const reference.
And std::advance
returns nothing (i.e. void
), so you can't use operator*
on it or compare it with it
.
The direct fixing will be like:
std::list<some_object>::iterator it = events.begin();
auto one_before_end = events.end();
std::advance(one_before_end, -1); // or --one_before_end;
while (it != one_before_end) events.erase(it++);
BTW: std::list::erase
has an overloading taking iterator range, so you can just:
events.erase(events.begin(), one_before_end);