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

《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");
}
时间: 2024-08-27 14:10:05

STL的hashtable默认支持的模板类型的相关文章

聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数] 较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源,如果采用物理文件作为配置源,我们可以选择不同的格式(比如XML.JSON和INI等) .如果这些默认支持的配置源形式还不能满足你的需求,我们还可以通过注册自定义ConfigurationSour

Struts2支持的结果类型

Struts2支持的结果类型 Struts2默认提供了一系列的结果类型,下面是struts-default.xml配置文件的配置片段:  <!-- 配置系统支持的结果类型 -->   <result-types>             <!-- Action链式处理的结果类型 -->             <result-type name="chain" class="com.opensymphony.xwork2.Action

大开测试:性能- VuGen中支持哪些步骤类型(连载12)

7.12  VuGen中支持哪些步骤类型 1.问题提出 VuGen中支持哪些步骤类型? 2.问题解答 VuGen中支持下列步骤类型,如表7-3所示. 表7-3                                                  VuGen支持步骤类型列表 步 骤 类 型 描    述 服务 服务步骤是一个函数,它不会在Web应用程序上下文中进行任何更改.更确切地说,服务步骤执行自定义任务(如设置代理服务器).提供授权信息以及发出自定义的标头 URL 在键入URL或者

jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?

1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML.在 1.4 中,JSON 就会生成一个 JavaScript 对象,而 script 则会执行这个脚本.随后服务器端返回的数据会根据这个值解析后,传递给回调 函数.可用值: •"xml": 返回

.NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源,如果采用物理文件作为配置源,我们可以选择不同的格式(比如XML.JSON和INI等) .如果这些默认支持的配置源形式还不能满足你的需求,我们还可以通过注册自定义ConfigurationSource的方式将其他形式数据作为我们的配置来源. [ 本文已经同

转载:ASP.NET MVC扩展自定义视图引擎支持多模板&amp;动态换肤skins机制

ASP.NET mvc的razor视图引擎是一个非常好的.NET MVC框架内置的视图引擎.一般情况我们使用.NET MVC框架为我们提供的这个Razor视图引擎就足够了.但是有时我们想在我们的项目支持多模板&skins机制,比如我们可能会有多套的模板,也就是多个View风格,而我们只需要改一下配置文件就可以轻松的改变页面的风格和模板.实现这个功能有两种方式: 一.使用接口IViewEngine自己完成一个类似Razor视图引擎的功能. 二.继承类RazorViewEngine类,重写它的一些方

【Java/Android性能优 4】PreloadDataCache支持预取的数据缓存,使用简单,支持多种缓存算法,支持不同网络类型,扩展性强

本文转自:http://www.trinea.cn/android/preloaddatacache/ 本文主要介绍一个支持自动向前或向后获取新数据的缓存的使用及功能.Android图片内存缓存可见ImageCache. 主要特性:(1).使用简单  (2).可自动预取新数据  (3).可选择多种缓存算法(包括FIFO.LIFO.LRU.MRU.LFU.MFU等15种)或自定义缓存算法  (4).省流量性能佳(有且仅有一个线程获取数据)  (5).支持不同类型网络处理  (6)缓存可序列化到本地

3.2 STL中的函数对象类模板

*: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. 2)less是STL中最常用的函数对象类模板,其定义如下: template<class _Tp> struct less { bool oprator()(const _Tp&_x,const _Tp&_y)const { return _c<_y; } } 要判断两个i

Android ImageCache图片缓存,使用简单,支持预取,支持多种缓存算法,支持不同网络类型,扩展性强

本文主要介绍一个支持图片自动预取.支持多种缓存算法的图片缓存的使用及功能.图片较大需要SD卡保存情况推荐使用ImageSDCardCache. 与Android LruCache相比主要特性:(1).  使用简单   (2). 轻松获取及预取新图片  (3).  可选择多种缓存算法(FIFO.LIFO.LRU.MRU.LFU.MFU等13种)或自定义缓存算法   (4).  省流量性能佳(有且仅有一个线程获取图片)   (5).  支持不同类型网络处理  (6).  可根据系统配置初始化缓存