4

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.

3
  • Just enforce the constraint that T1 has to be "hashable". I.e. a method that gives you the hash key must exist. Commented Apr 26, 2013 at 19:23
  • (Java solves this by making all objects hashable.) Commented Apr 26, 2013 at 19:23
  • You're aware there's std::unordered_set in C++11? It is a hash table in the Standard Library. Commented Apr 26, 2013 at 19:28

2 Answers 2

10

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.

Sign up to request clarification or add additional context in comments.

13 Comments

But, I want to implement my own hash table for a generic key. There must be some way in which it's implemented in STL. The implementation here is of use in a real life situation.
@Sankalp There is, and I already gave it to you: std::hash. For example, you would use std::hash<T1>. If there is no specialization for T1 when your HashTable template is instantiated, the compiler will give an error. If you are not the author of the type given by T1 then you cannot possibly hope to implement a correct hashing algorithm for it.
@PeterBecker Thank you for that edit... I have clearly not had enough caffeine yet.
I know std::hash<T1> would provide me with the hash value, I wanted to know how is it implemented in stl?
If you have the code of a type, you should be able to write a hash function. If you don't have the code, i.e. if you don't know how the type (class) works internally, then you cannot reasonably provide a hash value/function.
|
4

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

1 Comment

+1 for the suggestion to provide the hash implementation as a template parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.