有关STL中map的key是指针的情况分析和其他map使用注意点

比如有这么一个map:
map<TCHAR *, TCHAR *> map1;

这样当往map1中插入数据的时候,key是一个指针。在SDClient中,我们将文本资源读入一个map,然后将来使用literal的文本key字符串来将value取出,从而达到国际化的目的。

但是这里有一个问题就是,由于key是一个指针,所以当我们尝试用literal的TCHAR *来取出value时,发现value取不出来。这是因为插入数据时候的TCHAR *和我们取的时候的TCHAR *,两个指针的地址不一样。

那 应该怎么办呢?我们的目的其实是比较key指向的字符串,而不是key本身。但是查看了map的定义之后,发现map对key的要求就是要定义< operator。为什么map不需要key定义== operator呢?很自然的想法,< operator用来判断两个key的大小,从而决定key在map中排列的次序,而==用来判断两个key是否相等,从而在使用key引用value的 时候用上。

后来查阅了资料,发现定义一个< operator就足够了。当我们使用key来引用value的时候,map使用二分查找法,在map中搜索,如果map找到一个key,发现这个key 既不大于我们给的key,也不小于我们给的key,那么,map就认为这两个key相等,从而给出value。所以,只定义一个< operator就足够了。

所以,在map中使用指针作为key的type,应该这样做:

Code: Select all
struct cmp_str
{
   bool operator()(const TCHAR *a, const TCHAR *b)
   {
      return _tcscmp(a, b) < 0;
   }
};

typedef map<TCHAR *, TCHAR *, cmp_str>   TextResMap;


这样就OK了。map使用我们给定的cmp_str函数指针来判断两个key的大小,也判断两个key是否相等。

其他一些注意点和知识:

1. map内部使用一棵红黑树来存储数据。map不是hash_map,没有hash的特性。map只是一种关联容器,也称为映射容器。hash_map相比 map,查找的效率更高,因为hash_map会根据key,使用hash函数来为每个key生成一个hash value,下次通过key的hash value能很快的找到指定的key对应的entry。hash_map不是C++ 99标准规范中定义的stl中的一种类型,但是现在很多编译器厂商都实现了hash_map,至于怎么个用法请google "详细解释 hash_map"就能找到一篇很详细的文章。
2. map使用二分查找来查找key,所以耗费的时间是log2/N,N是所有entry的数目。所以,如果有16个entry,那么最多查找4次,如果有100万条entry,也最多查找20次就OK了。性能还是比较不错的。
3. 如果数组下标的方式来操作map,比如map1["Hello"]=1,有一个问题就是如果Hello这个key不存在,那么,就会自动创建一个出来。所 以,不能使用数组下标这种方式来判断指定的key在map中是否存在,而应该使用:find或insert方法。建议使用insert,因为在往map中 插入数据的时候,也使用insert,这样,通过判断insert的返回值,就知道是插入成功了,还是该key已经存在了。代码风格上非常的统一。当给定 key想查找value的时候,可以使用find。
posted @ 2011-04-10 14:47  super119  阅读(3899)  评论(0编辑  收藏  举报