0

I am trying to write simple hashtable in c++. My hashtable implementation template looks like this:

template<class k, class v, class h<k>, class e<k> >
class my_hash {


};

where
k = class type for key
v = class type for value
h = class type for hash fn
e = class type for equality fn

I have defined class h like this

template<class k>
class h {


};

I would specialize above template for different k types e.g. int, string etc. What I want to do is whenever I invoke my_hash template with k,it should automatically pick up the

h<k>

as the hash function type.For this to happen how do I define template ?

If I define it like I have shown it above, g++ gives compiler error saying h is not a template ? Could somebody please help me with this ?

cppdev
  • 6,833
  • 13
  • 40
  • 45
  • Why not just `class h, class e`? – mfontanini Apr 04 '13 at 04:28
  • I tried doing that. my_hash constructor will take class h as parameter. But is it possible to pickup h as default hash function even if I do not specify it in the constructor ? – cppdev Apr 04 '13 at 04:36

2 Answers2

2

I think what you need is called template template parameter and it is this:

template<class k, class v, template<typename> class h, template<typename> class e>
class my_hash 
{
  //then here you can intantiate the template template parameter as
  h<k> hobj;
  e<k> eobj;
  //...
};

Now you can pass class template (which takes one type argument) as the third and fourth template argument to the above class template. Look for template template parameter in your book, or online, know more about it. You can start from here:

Hope that helps.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Thanks Nawaz. Do you mean like my_hash, e > ? It is not working for me. – cppdev Apr 04 '13 at 05:01
  • @cppdev: No. `h` is NOT an argument for template template parameter, because `h` is NOT a template. `h` is a template, so you can do this : `my_hash`. Please go through the link to know about it in details. Know them as to how they work. Dont just guess. – Nawaz Apr 04 '13 at 05:03
  • Finally I got it working with following signature. template , class e =e1 > h and k have defualt values with h1 and e1 where h1 and e1 are actual templates. I will also give template template parameters a try. Thanks Nawaz!! – cppdev Apr 04 '13 at 05:37
  • With template template parameters also I need to give default values in order to make my my_hash constructor work like my_hash where in both ints specify key and value types and I do not need to bother about specifying the h and e types. templateclass h = h1 , template class e = e1 > – cppdev Apr 04 '13 at 05:52
  • @cppdev: Yes. You don't have to both about specifying types. – Nawaz Apr 04 '13 at 05:57
0

You can certainly use template template parameters, but your intended use case - where the template types are closely related - is a common one, that is idiomatically solved with traits.

With hash keys, usually the key type is closely related with the hash function and equality function. With traits you can do something like this silly example:

template <class T> struct key_hash_traits;

template <>
struct key_hash_traits<int>
{
    typedef int key_type;
    static size_t hash(int k) { return k*k / 42; }
};

template <class T, class V>
struct my_non_functioning_hash_table
{
    void insert(T::key_type t, V v)
    {
        if (T::hash(t) == 13)
        {
            std::cout << "hello world\n";
        }
    }
};

int main()
{
    int k = 256;
    my_non_functioning_hash_table<key_hash_traits<int>, float> h;
    h.insert(k, 3.14);
}

See how with key_hash_traits, all the interrelated types (key, hash func) are placed together, which is nice, and the definition of my_non_functioning_hash_table is simpler too as it only needs to refer to the trait. This example does assume you'll only ever have one hash func per key type, but you can easily modify that. I hope you get the general idea.

For more reading on traits, see these links:

congusbongus
  • 13,359
  • 7
  • 71
  • 99