Search code examples
c++liststllistiteratorstdlist

C++ List erase up to end()-1 elements in the list


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?


Solution

  • 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);