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

时间:2016-05-24 01:47:05

标签: c++ list stl listiterator stdlist

我有一个std::list<some_object> events,我想删除该列表中除最后一个之外的所有元素。所以我想到了(正如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++);

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

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)){

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

2 个答案:

答案 0 :(得分:6)

这是std::prev的一个典型用法。 如果你想remove除了最后一个元素之外的所有元素,最常用的方法是在你的结束迭代器上使用std::prev(基本上使用std::advance)。

myList.erase(myList.begin(), std::prev(myList.end()));

示例:

#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;
}

打印:

2

正如Remy Lebeau在评论中指出的那样,对于非C ++ 11编译器,您可以按songyuanyao's answer

中的说明使用std::advance()

答案 1 :(得分:1)

  

但是,不是list :: end应该返回一个迭代器吗?

是的,但是std::advance将非const引用作为其第一个参数,而event_heap.end()是一个临时变量,不能绑定到非const引用。

并且std::advance不返回任何内容(即void),因此您无法使用operator*或将其与it进行比较。

直接修复将如下:

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有一个超载的迭代器范围,所以你可以这样做:

events.erase(events.begin(), one_before_end);