C++ List 最多擦除列表中的 end()-1 个元素
C++ List erase up to end()-1 elements in the list
我有一个 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
不应该是 return 一个迭代器吗?我做错了什么?
But, isn't list::end supposed to return an iterator?
是的,但是 std::advance
将非常量引用作为其第一个参数,而 event_heap.end()
是一个临时变量,不能绑定到非常量引用。
和std::advance
returns什么都没有(即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++);
顺便说一句:std::list::erase
有一个重载获取迭代器范围,所以你可以:
events.erase(events.begin(), one_before_end);
这是 std::prev
的一种典型用法。
如果你想 remove all elements except the last one, the most idiomatic way to do it is by using 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 编译器,您可以只使用 std::advance()
,如
中所述
我有一个 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
不应该是 return 一个迭代器吗?我做错了什么?
But, isn't list::end supposed to return an iterator?
是的,但是 std::advance
将非常量引用作为其第一个参数,而 event_heap.end()
是一个临时变量,不能绑定到非常量引用。
和std::advance
returns什么都没有(即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++);
顺便说一句:std::list::erase
有一个重载获取迭代器范围,所以你可以:
events.erase(events.begin(), one_before_end);
这是 std::prev
的一种典型用法。
如果你想 remove all elements except the last one, the most idiomatic way to do it is by using 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 编译器,您可以只使用 std::advance()
,如