在实际的应用中,会碰到需要遍历容器中的元素,并且在判断某些的条件后,将某个元素从容器中清除的场景:
#include <stdio.h>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <deque>
template<class T>
void del(T t, int pos)
{
// 测试循环遍历中的删除操作
int i = 0;
for (typename T::iterator it = t.begin(); it != t.end(); ++i)
{
printf("%d ", *it);
if (i == pos)
{
t.erase(it++);
}
else
++it;
}
printf("\n");
}
int main()
{
std::map<int, int> mp;
std::set<int> st;
std::list<int> lt;
std::vector<int> vec;
std::deque<int> dque;
for (int i = 0; i < 10; ++i)
{
mp.insert(std::make_pair(i, i));
st.insert(i);
lt.push_back(i);
vec.push_back(i);
dque.push_back(i);
}
del(mp, 5);
del(st, 5);
del(lt, 5);
del(vec, 5);
del(dque, 5);
return 0;
}
注意上面的代码,it++或者++it,并不是发生在for循环头里面,而是在for循环体内,而当要进行删除时,应该使用
t.erase(it++);
it++这个重载操作会使it后移,并返回当前迭代位置。
运行上面的代码后,map、set、list正确输出了值,而当运行到vec或者dque后,会发生断言崩溃等情况,原因是执行erase后,it已经无效,导致下次循环时,取值失败。
因此需要注意以上这种循环遍历中删除元素,且不影响继续遍历的方式可以用于
关系容器中(map,list,set等),而线性容器(vector,deque等)
就会出现问题。
版权声明:本文为jwybobo2007原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。