C++列表擦除到end() - 列表中的1个元素

mau*_*zio 2 c++ stl list stdlist listiterator

我有一个std::list<some_object> events,我想删除该列表中除最后一个之外的所有元素.所以我想到了(正如这个帖子所建议的那样):

std::list<some_object>::iterator it = events.begin(); // Init iterator on top of list
while(it!=*std::advance(events.end(),-1)) events.erase(it++);
Run Code Online (Sandbox Code Playgroud)

不幸的是,上面的代码不起作用,因为它会产生错误:

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)){
Run Code Online (Sandbox Code Playgroud)

但是,是不是list::end应该返回迭代器?我究竟做错了什么?

Whi*_*TiM 6

这是一个典型的用法std::prev.如果要删除除最后一个元素之外的所有元素,最常用的方法是在末端迭代器上使用std::prev(基本上使用std::advance).

myList.erase(myList.begin(), std::prev(myList.end()));
Run Code Online (Sandbox Code Playgroud)

例:

#include <iostream>
#include <iterator>
#include <list>

int main(){
    std::list<int> ls = {3, 5, 9, 2};

    if(!ls.empty())
        ls.erase(ls.begin(), std::prev(ls.end()));

    for(auto x : ls)
        std::cout << x << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印:

2
Run Code Online (Sandbox Code Playgroud)

正如Remy Lebeau在评论中指出的那样,对于非C++ 11编译器,你可以std::advance()按照songyuanyao的回答中的说明使用