via: http://blog.sina.com.cn/s/blog_67b6b720010114d3.html
删除某个容器里的某个元素:c.erase(T);
看似一个简单的动作,然而对不同类型的容器,内部却做了截然不同的事情,后面介绍。
假设有这样一个题目,将某个容器中所有满足条件N == X的元素删除,按照常规的思路应该有类似这样的代码:
// 假设Container和container分别表示一种容器和对应的一个对象
Container<T>::iterator it;
for (it = container.begin(); it != container.end(); ++it) {
if (N == X)
container.erase(it);
}
然而这样的代码对于任一种容器都是错误的
容器按内存分配方式可以分为链表容器和数组容器。
所谓的链表容器指的是一种表现方式,包括list、slist等这样基于节点的容器 (动态分配内存块)和set、map、multiset、multimap等关联容器(平衡树实现),而数组容器指的是在一块连续的内存上保存元素的连续 内存容器,比如vector、deque、string等。
链表容器以list为例,当执行container.erase(it)时,确实第一 个满足条件的元素删除了,但这时it指针已经被删除了,它也不指向任何元素了,所以也只能到此为止了,也就是说上面的代码对于链表容器来说只能正确删除第 一个满足条件的元素,针对这个问题我们首先想到的就是在删除指针之前,给其做个备份。
将这个临时变量直接建立在erase实现里,这样做更简洁,也显得专业些。
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
lt.erase(it++); //这里是关键
else
++it;
}
链表容器使用erase删除节点还有一个特点,就是会将下一个元素的地址返回,所以也可以这样实现:
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
it = lt.erase(it);//自动返回下一个元素的地址,不用再主动前移指针
else
++it;
}
数组容器以vector为例,当执行container.erase(it)时,和上面提到的一样,第一个满足条件的元素删除了,但这时数组容器不允许中间有“空隙”,所以会做个大动作,就是将被删元素后面所有的元素前移(参考STL源码),而数组容器记录的是下标,所以删除元素后,当前下标定位的元素也就顺理成章的变成了原有队列中的下一个元素,同样以删除偶数为例,代码如下:
vector<int>::iterator it = v.begin();
for (it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0)
v.erase(it);//删除元素后,后面元素自动往前移,不用挪动指
else
++it;
}
网上有说在VS2005里面上面的v.erase(it)写法是行的 VS2008及2010却运行会出现错误 会出现
vector erase iterator outside range 最保险的做法是将v.erase(it)改成 it=v.erase(it)
相关推荐
STL中map用法详解 STL中map用法详解 STL中map用法详解
STL中list的使用
stl中文手册 doc文档哦 stl中文手册 doc文档哦 stl中文手册 doc文档哦 stl中文手册 doc文档哦
stl STL编程 C++ STL使用教程 stl 电子书两本(C++ STL使用教程,STL编程)
使用STL中的VECTOR LIST 容器实现学生管理系统,代码实现增删差改
很详细全面的stl教程,包含非常详细的c++ stl使用教程及编程教学
很不错的文档 值得一看!三十分钟掌握STL,STL使用技巧
STL入门 STL入门 STL入门 STL入门 STL入门 STL入门
总结的STL中vector map list的使用方法和误区
下面小编就为大家带来一篇关于STL的erase()陷阱-迭代器失效问题的总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
STL模板类使用详解STL模板类使用详解STL模板类使用详解STL模板类使用详解STL模板类使用详解STL模板类使用详解
STL容器的一些使用简介
使用STL编程 条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46:考虑使用函数对象代替...
STL中的string介绍,以及如何合起来使用的方法
在删除选项中仔细选择 条款10:注意分配器的协定和约束 条款11:理解自定义分配器的正确用法 条款12:对STL容器线程安全性的期待现实一些 vector和string 条款13:尽量使用vector和string来代替动态...
STL中文手册(最新整理)
实现统计一段文章的每个单词的个数...其中CountDemo使用STL中的Map来实现的 CountDemo2是用一般语言实现,没有用到STL实现的; MapCount是用STL中的Vector和Map共同实现的 此题目是学习STL中的Map和Vector必练的经典题目
stl中map用法详解
怎么使用stl 这里几乎都有说明 条款1: 仔细选择你要的容器 条款2: 小心对“容器无关代码”的幻想 条款3: 使容器里对象的拷贝操作轻量而正确 条款4: 用empty来代替检查size是否为0 条款5: 尽量使用范围成员函数...
C++使用手册,C++程序员必备指导资料,查询STL类使用、算法等