template<class T>
inline void hash_combine(std::size_t & seed, const T & val){
seed ^= hash<T>()(val)+0x9e3779b9 + (seed << 6) + (seed >> 2);
}
template<class T>
inline void hash_val(std::size_t & seed, const T & val){
hash_combine(seed, val);
}
template<class T,class ...Types>
inline void hash_val(std::size_t & seed, const T & val,const Types & ...args){
hash_combine(seed, val);
hash_val(seed, args...);
}
template<class ...Types>
inline size_t hash_val(const Types & ...args){
size_t seed = 0;
hash_val(seed, args...);
return seed;
}
上面是一个万能的hash函数,可以把任意的对象,转换成hash值。
当我们使用一个容器的时候,我们必须为我们存储的元素,写一个hash function。
我们有以下几种方法:
1、把hash function 作为一个成员函数。
class Customer{
public:
string name;
int age;
double money;
};
//方式三
class CustomerHash{
public:
size_t operator()(const Customer & c){
return hash_val(c.age);
}
};
unordered_set<Customer, CustomerHash> custset2; //这个是函数的调用
2、把hash function 作为一个普通函数。
size_t customer_hash_func(const Customer & c){
return hash_val(c.age);
}
//函数的调用
unordered_set<Customer, size_t(*) (const Customer &)> custset(20, customer_hash_func);
3、把hash function 作为一个仿函数。
//1、自己定义hash 函数的方式
namespace std //必須放在 std 內
{
template<>
struct hash<MyString> //這是為了 unordered containers
{
size_t operator()(const MyString& s) const // noexcept
{ return hash<string>()(string(s.get())); }
//借用現有的 hash<string> (in ...\include\c++\bits\basic_string.h)
};
}
unordered_set<MyString, hash<MyString>> set; //函数的调用