map中的erase成员函数用法
转载于 http://www.cnblogs.com/graphics/archive/2010/07/05/1771110.html
http://hi.baidu.com/sdkinger/item/dcad78e374707ff12b09a453
一、
#include <iostream>
#include <map>
#include <string>
using namespace std ; int main(void)
{
map<int, string> m ;
m.insert(pair<int, string>(, "abc")) ;
m.insert(pair<int, string>(, "def")) ;
m.insert(pair<int, string>(, "def")) ;
m.insert(pair<int, string>(, "ghi")) ; map<int, string>::iterator itor ; // 错误的写法
for (itor = m.begin(); itor != m.end(); ++itor)
{
if (itor->second == "def")
{
m.erase(itor) ; // map是关联式容器,调用erase后,当前迭代器已经失效
}
} // 正确的写法
for (itor = m.begin(); itor != m.end();)
{
if (itor->second == "def")
{
m.erase(itor++) ; // erase之后,令当前迭代器指向其后继。
}
else
{
++itor;
}
} // 另一个正确的写法,利用erase的返回值,注意,有些版本的stl-map没有返回值,比如SGI版,但vc版的有
for (itor = m.begin(); itor != m.end();)
{
if (itor->second == "def")
{
itor = m.erase(itor) ; // erase的返回值是指向被删除元素的后继元素的迭代器
}
else
{
++itor;
}
} // Print m
map<int, string>::const_iterator citor ;
for (citor = m.begin(); citor != m.end(); ++citor)
{
cout << citor->first << ":" << citor->second << endl ;
} getchar() ;
return ;
}
二、
STL的map表里有一个erase方法用来从一个map中删除掉指令的节点
eg:map<string,string> mapTest;
typedef map<string,string>::iterator ITER;
ITER iter=mapTest.find(key);
mapTest.erase(iter);
像上面这样只是删除单个节点,map的形为不会出现任务问题,
但是当在一个循环里用的时候,往往会被误用,那是因为使用者没有正确理解iterator的概念.
像下面这样的一个例子就是错误的写法,
eg.for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter);
}
这是一种错误的写法,会导致程序行为不可知.究其原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。
可以用以下方法解决这问题:
正确的写法
1.使用删除之前的迭代器定位下一个元素。STL建议的使用方式for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter++);
}
2. erase() 成员函数返回下一个元素的迭代器for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
iter=mapTest.erase(iter);
}
注意:
map的earse应注意:
map这种容器的下边访问和Vector等容器的下标访问有本质的区别。
对于Vector容器,用aVector[i]访问第i个元素时,如果元素不存在,容器不会增加元素,
而对于map,用aMap[key]
访问键key对应的对象时,如果该键对应的对象存在,则返回该对象(这和Vector一样),但是,当键值为key的元素不存在时,容器会自动的增加一个pair,键为key,而值则为一个容器定义时指定的类型并默认初始化(即,如果该类型为基本类型,则初始化为0,比如本例中,aMap[1]的使用会产生一个pair,<1,NULL>,若该类型为类类型,则调用默认构造函数初始化之)
显然,本例中,aMap[1]为NULL,后面的erase()不会执行,使得后面的
插入语句aMap.insert(1,new A())键值冲突
eg:如下代码会导致错误
#include <iostream>
#include <map>
using namespace std;
struct A
{
A(int i)
{
x=i;
}
int x;
};
int main()
{
map<int,A*> amap;
if ( amap[1] != NULL )
amap.erase(1);
amap.insert(make_pair(1,new A(1)));
amap.insert(make_pair(2,new A(2)));
amap.insert(make_pair(3,new A(3)));
return 0;
}
map中的erase成员函数用法的更多相关文章
- 在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static
在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create ...
- jquery中attr()与prop()函数用法实例详解(附用法区别)
本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是a ...
- python中enumerate()函数用法
python中enumerate()函数用法 先出一个题目:1.有一 list= [1, 2, 3, 4, 5, 6] 请打印输出:0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 打印输 ...
- C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解
http://blog.csdn.net/gmstart/article/details/7046140 在C++的类定义里面,可以看到类似下面的定义: 01 class List { 02 priv ...
- C++中的string常用函数用法
标准c++中string类函数介绍 注意不是CString 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而 ...
- c++中的string常用函数用法总结!
标准c++中string类函数介绍 注意不是CString 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作 ...
- [转]c++中的string常用函数用法总结
标准c++中string类函数介绍 注意不是CString之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作为 ...
- (C/C++学习)3.C++中cin的成员函数(cin.get();cin.getine()……)
说明:流输入运算符,在一定程度上为C++程序的开发提供了很多便利,我们可以避免C语言那种繁琐的输入格式,比如在输入一个数值时,还需指定其格式,而cin以及cout则不需要.但是cin也有一些缺陷,比如 ...
- php中sprintf与printf函数用法区别
下面是一个示例:四舍五入保留小数点后两位 代码如下 复制代码 <?php$num1 = 21;echo sprintf("%0.2f",$num1)."<b ...
随机推荐
- SQL中各数据类型的长度、精度
在 Microsoft? SQL Server? 中,每个列.局部变量.表达式和参数都有一个相关的数据类型,这是指定对象可持有的数据类型(整型.字符.money 等等)的特性. SQL Server ...
- html有序列表和无序列表
css控制UL LI 的样式详解(推荐) CSS: 代码如下: #menu ul {list-style:none;margin:0px;} #menu ul li {float:left;} 代码如 ...
- 利用ExcelDataReader封装类 导入表格数据
nuget 添加Install-Package ExcelDataReader
- 纯css3 开关按钮
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- javascript笔记——jquery.each中使用continue和break的方式
jQuery.each中continue的方式是 return true break 的方式是return false
- 而在Jquery中则使用$.map()、$.each()来操作数组
首先是普通的数组(索引为整数的数组): //$.map(arr,fn); //对数组中的每个元素调用fn函数逐个进行处理,fn函数将处理返回最后得到的一个新的数组 var arr = [9, 8, 7 ...
- [大牛翻译系列]Hadoop(2)MapReduce 连接:复制连接(Replication join)
4.1.2 复制连接(Replication join) 复制连接是map端的连接.复制连接得名于它的具体实现:连接中最小的数据集将会被复制到所有的map主机节点.复制连接有一个假设前提:在被连接的数 ...
- 【转】Web标准中的常见问题
本文转自http://www.tracefact.net/Misc/Common-Problems-Of-Web-Standard.aspx 引言 大概在2004年的时候,Web标准的概念藉由一本名为 ...
- 1105. Spiral Matrix (25)
This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasi ...
- ActiveMQ之Queue
Queue实现的是点到点模型,在以下的例子中,启动2个消费者共同监听一个Queue,然后循环给这个Queue发送多个消息. 代码如下: public class QueueTest { /** * @ ...