一、序列式容器
序列式容器(如 vector, deque)的迭代器删除正确的做法如下:
1 // 在这里想把等于2的元素都删除 2 for(auto it=q.begin();it!=q.end();) 3 { 4 if(*it==2) 5 { 6 it=q.erase(it); // 这里会返回指向下一个元素的迭代器,因此不需要再自加了 7 } 8 else 9 { 10 it++; 11 } 12 }
二、链表式容器
对于链表式容器(如 list),删除当前的 iterator,仅仅会使当前的 iterator 失效,这是因为 list 之类的容器,使用了链表来实现,插入、删除一个结点不会对其他结点造成影响。只要在 erase 时,递增当前 iterator 即可,并且 erase 方法可以返回下一个有效的 iterator。
方式一:递增当前 iterator
1 for (iter = cont.begin(); it != cont.end();) 2 { 3 (*iter)->doSomething(); 4 if (shouldDelete(*iter)) 5 cont.erase(iter++); 6 else 7 iter++; 8 }
方式二:通过 erase 获得下一个有效的 iterator
1 for (iter = cont.begin(); iter != cont.end();) 2 { 3 (*it)->doSomething(); 4 if (shouldDelete(*iter)) 5 iter = cont.erase(iter); //erase删除元素,返回下一个迭代器 6 else 7 ++iter; 8 }
三、关联式容器
例如map、set;
删除当前的iterator,仅仅会使当前的iterator失效,只要在erase失效,只要在erase时递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删除元素的迭代器先来看一下map迭代器失效的一个例子。
问题:
for (it = m.begin(); it != m.end(); it++) { if ((it->first)>5) m.erase(it); }
解决问题:
方法一:
for (it = m.begin(); it != m.end(); ) { if (it->first==5) m.erase(it++);//先把iter传值到erase里面,然后iter自增,然后执行erase,所以iter在失效前已经自增了 it++; }
方法二:
for (it = m.begin(); it != m.end(); ) { if (it->first==5) { it = m.erase(it);//获得有效的迭代器 } else {
++it; } }
发上等愿,结中等缘,享下等福;择高处立,就平处坐,向宽处行。