简体   繁体   English

如何在C ++中实现通用哈希函数

[英]How to implement a generic hash function in C++

I am trying to implement HashTable in C++ via templates. 我试图通过模板在C ++中实现HashTable。 Here is the signature: 这是签名:

template<class T1, class T2>
class HashTable {

public:
void add(T1 a, T2 b);

void hashFunction(T1 key, T2 value)
{

// how to implement this function using key as a generic 
// we need to know the object type of key

}
};

So, I am unable to move ahead with implementation involving a generic key. 因此,我无法推进涉及通用密钥的实现。

In Java, I could have easily cast the key to string and then be happy with implementing the hash for a key as string. 在Java中,我可以轻松地将键转换为字符串,然后很高兴将键的哈希实现为字符串。 But, in C++, what I know is that there is a concept of RTTI which can dynamically cast an object to the desired object. 但是,在C ++中,我所知道的是有一个RTTI概念可以动态地将对象转换为所需的对象。

How to implement that dynamic cast, if this method is correct at all? 如果这个方法是正确的,如何实现动态转换?

If using template is not the correct approach to implement generics for this case, then please suggest some better approach. 如果在这种情况下使用模板不是实现泛型的正确方法,那么请建议一些更好的方法。

You would typically use std::hash for this, and let type implementors specialize that template as required. 您通常会使用std::hash ,并让类型实现者根据需要专门化该模板。

size_t key_hash = std::hash<T1>()(key);

There is no way you can generically implement a hash function for any random type you are given. 对于您给出的任何随机类型,您无法一般地实现哈希函数。 If two objects are equal, their hash codes must be the same. 如果两个对象相等,则它们的哈希码必须相同。 You could simply run the raw memory of the objects through a hash function, but the types might implement an operator== overload that ignores some piece of object data (say, a synchronization object). 您可以通过哈希函数简单地运行对象的原始内存,但这些类型可能会实现一个忽略某些对象数据(例如,同步对象)的operator==重载。 In that case you could potentially (and very easily) return different hash values for equal objects. 在这种情况下,您可以(并且非常容易地)为相同的对象返回不同的哈希值。

It's strange that you want hash both key and value. 奇怪的是你想要哈希键和值。 How you will be able to get value by only key after it? 你之后如何才能通过钥匙获得价值?

If you are using C++11 good idea is to use std::hash<T1> that provided for some types (integers, string, pointers) and maybe specialized for other classes. 如果您正在使用C ++ 11,那么好主意就是使用为某些类型(整数,字符串,指针)提供的std::hash<T1> ,并且可能专门用于其他类。 Besides, it's good idea to allow change it using third template parameter class. 此外,允许使用第三个模板参数类进行更改是个好主意。 See how unordered_map is done 了解unordered_map是如何完成的

template<typename K, typename V, typename H = std::hash<T>>
class HashTable {
   //...
   void hashFunction(const T1& key) {
        hash = H()(key);
        //process hash somehow, probably you need get reminder after division to number of buckets or something same
        return hash % size;
   }
}

It seems impossible to write you own hasher, that will work OK for most types, because equality operator maybe overridden in some complicated way 编写自己的哈希似乎是不可能的,对大多数类型来说都可以正常工作,因为可能会以某种复杂的方式覆盖相等运算符

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM