Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a generic hash function in C++

I am trying to implement HashTable in C++ via templates. 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. But, in C++, what I know is that there is a concept of RTTI which can dynamically cast an object to the desired object.

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.

like image 428
Sankalp Avatar asked Dec 08 '22 15:12

Sankalp


2 Answers

You would typically use std::hash for this, and let type implementors specialize that template as required.

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). In that case you could potentially (and very easily) return different hash values for equal objects.

like image 73
cdhowie Avatar answered Dec 11 '22 11:12

cdhowie


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. Besides, it's good idea to allow change it using third template parameter class. See how unordered_map is done

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

like image 21
RiaD Avatar answered Dec 11 '22 12:12

RiaD