Template Partial Specialization with a Template?

Albert C. Baker III's Avatar, Join Date: Jun 2007
Newbie Member
Here is my problem. I am using one of the implementations of TR1 that
has a hash_map template.

for all the simple types hash_map<Key,Data> works because

Code:
namespace std
{
  template<typename T>
  struct hash
  {
    size_t operator(const T&t) {  }
  };
};
has been specialized for them (i.e. int, char, bool, etc)

If you want to write your own key type, you can:

Code:
struct MyKey
{
  int x;
  int y;
};

namespace std
{
    template<>
    struct hash<MyKey>
    {
      size_t operator()(const MyKey &mk) { return x<<16 + y; }
    };
};
My problem is this:

I have a template class thus:

Code:
template<typename T>
class TKey
{
  size_t hash() { return // hashy number }
  .
  .
  .
};
I can't figure out what the syntax is to define a std::hash<> specialization
that will implicitly specialize any specialization of the generic TKey template.
The inner code should be very simple:

Code:
template<>
hash<KeyType>
{
  size_t operator()(const KeyType &k) { return k.hash(); }
};
but my research has given me no clues into how to wrap this in some
kind of template mechanism that allows me to specify that this should be
a generic template that can be specialized against a particular specialization
of a TKey.
Albert C. Baker III's Avatar, Join Date: Jun 2007
Newbie Member
My office mate and I found the answer last night...

so, given my key type:

Code:
template<typename T_DataList,typename T_ColumnName,typename T_CDR>
class GenericDataContainerKey
{
  .
  .
  .
  size_t hash() { return m_datum << 3 + m_cdr.hash(); } // recursive data structure
};
the desired code snippet was:

Code:
namespace __gnu_cxx
{

  template<>
  template<typename T_DataList,typename T_ColumnName,typename T_CDR>
  struct hash<GenericDataContainerKey<T_DataList,T_ColumnName,T_CDR> >
  {
    size_t operator() (const GenericDataContainerKey<T_DataList,T_ColumnName,T_CDR> &tk) const { return tk.hash(); }
  };
};
This indicates a level of template behaviour that I was heretofore unaware, i.e.
that it is legal to nest template definitions and partial specializations.

That is what we are doing here; the outer 'template<>' is an indicator that
we want to do a partial specialization of our 'struct hash'. The inner
template<...> is a standard template definition, and the nesting of the two
allows us to specify a templated definition of the partial specialization,
as desired.