erase的作用是,使作为参数的迭代器失效,并返回指向该迭代器下一参数的迭代器。
如下:
list ParticleSystem; list::iterator pointer; if(pointer->dead == true) { pointer = ParticleSystem.erase(pointer); }
有一段关于错误使用erase的程序
using namespace std; int main() { std::listtest_list; std::list::iterator test_list_it; test_list.push_back(1); test_list_it = test_list.begin(); for(;test_list_it != test_list.end();test_list_it++) { test_list.erase(test_list_it); } }
问题:该程序不能跳出循环
原因:test_list.erase(test_list_it);每次做erase时都有可能使迭代器失效,test_list_it++就发生错误了。可以参见effective stl一书。所有容器做erase操作时都有可能使迭代器失效。
改为:
for(;test_list_it != test_list.end();) { test_list.erase(test_list_it++); }
or
for(;test_list_it != test_list.end();) { std::list::iterator iter_e=test_list_it++; test_list.erase(iter_e); }
注意:
for(;test_list_it != test_list.end();test_list_it++;) { std::list::iterator iter_e=test_list_it; test_list.erase(iter_e); }
这样仍然是错误的,原因是:iter_e=test_list_it 是指针值的复制,它俩其实指向同一个位置,所以iter_e失效那么test_list_it也会失效,所以test_list_it++就会有问题
如果是
for(;test_list_it != test_list.end();) { std::list::iterator iter_e=test_list_it++; test_list.erase(iter_e); }
则没有问题。
以上转自:http://blog.sina.com.cn/s/blog_782496390100rtyp.html
remove函数也存在erase函数同样的问题,但remove函数返回值是空,erase返回指向下一个元素的迭代器。
下面是一个简单的例子。
#include "stdafx.h" #include <stdio.h> #include <string.h> #include <malloc.h> #include <list> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { printf("------------------------------ Start\n"); list<int> ls; printf("ls.empty() = %d \n", ls.empty()); printf("ls.max_size() = %d \n", ls.max_size()); printf("ls.size() = %d \n", ls.size()); ls.push_back(1); ls.push_back(2); ls.push_back(3); printf("\n--------- after push 1, 2, 3 ---------\n"); printf("ls.empty() = %d \n", ls.empty()); printf("ls.max_size() = %d \n", ls.max_size()); printf("ls.size() = %d \n", ls.size()); for (list<int>::iterator i = ls.begin(); i != ls.end(); i++) { printf("%d, ", *i); } printf("\n------------------------------\n"); for (list<int>::iterator i = ls.begin(); i != ls.end(); ) { printf("erase %d \n", *i); ls.erase(i++); } printf("\n--------- after erase ---------\n"); printf("ls.empty() = %d \n", ls.empty()); printf("ls.max_size() = %d \n", ls.max_size()); printf("ls.size() = %d \n", ls.size()); printf("\n------------------------------\n"); ls.push_back(1); ls.push_back(2); ls.push_back(3); for (list<int>::iterator i = ls.begin(); i != ls.end(); ) { printf("remove %d \n", *i); ls.remove(*i++); } printf("\n--------- after remove ---------\n"); printf("ls.empty() = %d \n", ls.empty()); printf("ls.max_size() = %d \n", ls.max_size()); printf("ls.size() = %d \n", ls.size()); printf("\n------------------------------ End\n"); getchar(); return 0; }
其中:
for (list<int>::iterator i = ls.begin(); i != ls.end(); ) { printf("erase %d \n", *i); ls.erase(i++); }
也可以写成下面的形式,因为erase函数的返回值就是指向下一个元素的迭代器。
for (list<int>::iterator i = ls.begin(); i != ls.end(); ) { printf("erase %d \n", *i); i = ls.erase(i); }
输出结果如下:
------------------------------ Start
ls.empty() = 1
ls.max_size() = 1073741823
ls.size() = 0
--------- after push 1, 2, 3 ---------
ls.empty() = 0
ls.max_size() = 1073741823
ls.size() = 3
1, 2, 3,
------------------------------
erase 1
erase 2
erase 3
--------- after erase ---------
ls.empty() = 1
ls.max_size() = 1073741823
ls.size() = 0
------------------------------
remove 1
remove 2
remove 3
--------- after remove ---------
ls.empty() = 1
ls.max_size() = 1073741823
ls.size() = 0
------------------------------ End