Chinaunix首页 | 论坛 | 博客
  • 博客访问: 150412
  • 博文数量: 20
  • 博客积分: 1515
  • 博客等级: 上尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-14 10:06
文章分类

全部博文(20)

文章存档

2011年(2)

2010年(4)

2009年(14)

我的朋友

分类: C/C++

2010-02-25 11:39:34

 

 

这是在学习STL过程中遇到的一些问题,现记录下来

 

1  注意map[]操作符;

 

  map的下标运算符[]的作用是:将关键码作为下标去执行查找,并返回对应的值;如果不存在这个关键码,就将一个具有该关键码和值类型的默认值的项插入这个map

 map mapTest;

 

// []操作符可以方便快速的给map添加内容

mapTest ["StarLee"] = "123";

if (mapTest ["LiXing"] == "234")

{

    mapTest ["LiXing"] = "345";

}

对于上面的代码来说,if (mapTest ["LiXing"] == "234")这行代码首先去查询map中是否有关键码为LiXing的项,结果发现没有该项,于是就向map中插入了一项<"LiXing", "">sting的默认值为空字符串)。

 

 

2  注意使用erase();

 

 STLmap表里有一个erase方法用来从一个map中删除掉指令的节点

eg:

map mapTest;

typedef map::iterator ITER;

ITER iter=mapTest.find(key);

mapTest.erase(iter);

像上面这样只是删除单个节点,map的形为不会出现任务问题,

但是当在一个循环里用的时候,往往会被误用,那是因为使用者没有正确理解iterator的概念.

像下面这样的一个例子就是错误的写法,

eg.

for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)

{

cout<first<<":"<second<

mapTest.erase(iter);

}

这是一种错误的写法,会导致程序行为不可知.究其原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。

可以用以下方法解决这问题:

正确的写法

 

1.使用删除之前的迭代器定位下一个元素。STL建议的使用方式

for(ITER iter=mapTest.begin();iter!=mapTest.end();)

{

cout<first<<":"<second<

mapTest.erase(iter++);

}

在删除iter的时候,先将iter做一个副本,然后执行iter++使之指向下一个结点,再进入erase函数体中执行删除操作,删除时使用的iter是先前保存的副本,

erase() 成员函数返回下一个元素的迭代器

for(ITER iter=mapTest.begin();iter!=mapTest.end();)

{

cout<first<<":"<second<

iter=mapTest.erase(iter);

}

 

3  初始化, 不要轻易零初始化string, vectorstl标准容器及具有动态内存管理的类。不要从内存级别改变对象级别的东西。

 

 

4  hash_set, hash_maplinux下编译出现not declared的解决方法:

 

hash_map本身以前本身不属于标准库,是后来引入的.

有两种可能:

一种可能它被放在了stdext名空间里,那么你就要使用using namespace stdext 引入该名空间并#include ;.

另一种可能就是它被反在了标准库的ext目录底下,仍旧属于std名空间

这时你的源文件应当包含头文件

#include ;

 

如果不知道的话.可以使用

切换到你的stl库目录底下cd /usr/include/c++/版本

然后grep -iR "hash_map" ./

查看在哪个文件中.一般头文件的最后几行会提示它所述的名空间.

编译出现not declared的解决方法:

using namespace __gnu_cxx;

或者  __gnu_cxx:: hash_map;

5 

阅读(1770) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~