STL的hashtable默认支持的模板类型

5 篇文章 0 订阅

      《STL源码剖析》的5.7.7 hash function一节中介绍了<stl_hash_fun.h>中定义了数个现成的hash函数,全都是仿函数。这些hash函数支持的模板类型包括:char*, const char*, char, unsigned char, signed char, short, unsigned short, int , unsigned int, long, unsigned long。这些不同类型的hash函数是通过对以下类模板实例化得到的:

template<class T> struct hash { }

大部分内置的hash函数内部并没有做什么,只是返回原值,例如针对short的hash函数如下:

__STL_TEMPLATE_NULL struct hash<short> {
     size_t operator() (short x) const { return x; }
};

对于字符串类型(char *和 const char *),hash函数内部调用了__stl_hash_string,源码如下:

inline size_t __stl_hash_string(const char *s) {
	unsigned long h = 0;
	for ( ; *s; ++s)
		h = 5*h + *s;

	return size_t(h);
}

__STL_TEMPLATE_NULL struct hash<char *> {
	size_t operator() (const char * s) const {
		return __stl_hash_string(s);
	}
};


       由此可见,SGI STL的hashtable无法处理除上述类型以外的元素,例如string, double, float等。也就是说,如果定义unordered_set<string>,并向其中添加string对象时,编译无法通过。因为unordered_set内部使用的就是hashtable,并且没有内置的hash函数来处理string类型。

unordered_set的类定义如下:

template <class Value,
	class HashFcn = hash<Value>,
	class EqualKey = equal_to<Value>,
	class Alloc = alloc>
class unordered_set {

};

第二个模板参数指明了默认的hash函数,但当Value实例化为string时,找不到相应的hash<string>,编译报错, 要想 unordered_set支持string, 必须为string自定义hash函数。代码如下:

#include <unordered_set>
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;

template<>            //模板实例化
struct hash<string> {
	size_t operator()(string str) {
		unsigned long h = 0;
		for(string::size_type i = 0; i != str.size(); i++) {
			h = 5*h + str[i];
		}
		return size_t(h);	
	}
};

int main () {
	unordered_multiset<string> ihs; 
	string str;

	cout << ihs.bucket_count() << endl;

	ihs.insert(string("abc"));
	ihs.insert(string("def"));
	str.assign("kkk");

	ihs.insert(str);
	ihs.insert("abc");

	assert(ihs.find(str) != ihs.end());

	for(unordered_multiset<string>::iterator it = ihs.begin(); it != ihs.end(); it++) {
		cout << *it << endl;
	}
	system("pause");
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值