[STL] __gnu_cxx::hash_map使用中的一些问题
来源:互联网 发布:网龙网络怎么样 编辑:程序博客网 时间:2024/06/05 15:51
今天看《libstdc++ manual 20110201》中提到这个hash_map是为了向后兼容SGI/HP的代码,但是已经被废弃了,取而代之的是C++0x中的unordered_map/unordered_multimap,在tr1文件夹中(老版本的编译器一般不带这个文件夹)。
==============================================================================
这个不是gcc标准库的一部分,而是扩展ext中的一个功能,他提供了一个哈希表的实现。定义如下:
template<class _Key, class _Tp, class _HashFcn = hash<_Key>, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > class hash_map;
可见,如果定义完整的hash_map,需要提供<key类型,value类型,哈希函数,key相等判断函数,value类型内存分配器>等5个模板参数,由于后三个都有默认值,所以一般我们只需要提供前两个。
1> 定义__gnu_cxx::hash_map<string, int> myHash;不会出错,然而一旦对myHash进行操作,就会出现编译错误,“instantiated from here”,这是因为gnu版本的hash_map只实现了有限的几个hash模板函数(见第三个模板参数,这些函数在hash_fun.h中),而这些函数里包括hash<const char*>,但是不包括hash<std::string>的实例化。解决办法是定义哈希表前自己定义一个实例,这样编译器就知道调用这个函数了。
namespace __gnu_cxx{template<> struct hash<std::string>{size_t operator()(const std::string &s) const{ return hash(s.c_str()); }}}
2> 发现了gnu帮我们实现了hash<const char*>/hash<char*>的版本,那么实际上,有时候就可以直接利用这个版本了。然而还是会出现新的问题:
__gnu_cxx::hash_map<char*, int> myHash;char name1[10] = "panda";char name2[10] = "panda";myHash[name1] = 1;__gnu_cxx::hash_map<char*, int>::iterator hit = myHash.find( name2 );if( myHash.end() == hit ) printf( "Not Find\n" );
你会发现,虽然name1和name2都是panda,但是插入了name1,用name2去查找时,还是查无结果。这是涉及到第四个模板参数,判断key相等,默认的是std::equal_to,而这个函数的定义是用operator==来进行判断的,指针的相等当然就是地址一样了,而name1和name2的地址显然不同。解决办法是用自己指定的函数模板替代默认的。
template <class _Tp>struct my_equal_to : public binary_function<_Tp, _Tp, bool>{ bool operator()(const _Tp& __x, const _Tp& __y) const { return strcmp( __x, __y ) == 0; }};// 定义哈希表时,用如下方法(这次不能跳过第三个模板参数,所以要指定):__gnu_cxx::hash_map< char*, int, __gnu_cxx::hash<char*>, my_equal_to<char*> > myHash;
3> 遍历__gnu_cxx::hash_map出现了死循环,这个问题并不常见,然而遇到了可能真让人摸不到头脑。还好我之前见过这篇帖子,没有在这里陷很久。
http://blog.csdn.net/tototony/article/details/5689882
这个问题简单说来,就是gnu的实现是,内部有个_M_Cur指针指示当前位置A,每次计算operator++,都用当前位置的key调用hash函数计算下一个位置B,如果key传入hash_map以后,又在外部将其内容破坏,导致hash函数计算后的B位置在A位置之前,那么从B到达A以后,又会跳回B,形成B-A区间的死循环。
- [STL] __gnu_cxx::hash_map使用中的一些问题
- [STL] __gnu_cxx::hash_map使用中的一些问题
- __gnu_cxx::hash_map使用中的一些问题
- __gnu_cxx::hash_map使用中的一些问题
- STL中的hash_map使用
- STL中的hash_map
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- c++ STL hash_map 使用
- STL hash_map使用
- STL hash_map使用
- STL hash_map使用
- 参考---sql发布订阅
- mapreduce理解
- 博客网址大全
- MFC 对话框最大化时控件也随比例最大化或者还原
- inttypes.h
- [STL] __gnu_cxx::hash_map使用中的一些问题
- Oracle Index Clustering Factor 说明
- 技术细节点滴
- linux mknod命令解析
- AC解 - Life Forms(POJ#3294)
- string 和 StringBuilder 的区别
- 如何查看域名绑定几个ip
- datatable删除行、列
- 在Ext.grid.GridPanel中每次都显示最后一条记录