如何创建可以参数化的哈希函数?

时间:2014-02-23 15:59:02

标签: c++ stl

我想创建模板类型T和E支持的哈希函数。 我用:

  namespace std {
   namespace tr1 {
    template<class T, class E> struct hash<my_class<T, E> >
    {
      public:
       size_t operator()(const my_class<T, E>& k) const
           {
               return ((hash<T>()(k.a()))^ (hash<E>()(k.x()) << 1) >> 1);
       }
     };
    }
  }

但我收到的错误如下:

 In file included from g.cpp:1:
 g.h:35: error: ‘hash’ is not a template
 g.h:36: error: explicit specialization of non-template ‘hash’
 g.h:76: error: ‘hash’ is not a template
 g.h:76: error: ‘hash’ is not a template type

是否无法专门化哈希函数以便它可以使用模板?

如果没有,我将如何构建一个基于泛型类型T和E的散列函数?

编辑:有人在下面回答,但不完全是我的问题。我感兴趣的是能够定义一个本身使用泛型类型的哈希函数。类似哈希的东西&lt; some_class&lt; T> &GT;其中T是泛型类型。

2 个答案:

答案 0 :(得分:2)

hash 位于名称空间std中,不在名称空间std::tr1中。请参阅en.cppreference.com中的代码段,了解如何对其进行专门化的示例(当然,您也可以对其进行部分专业化):

#include <iostream>
#include <functional>
#include <string>

struct S
{
    std::string first_name;
    std::string last_name;
};

namespace std
{
    template<>
    struct hash<S>
    {
        typedef S argument_type;
        typedef std::size_t value_type;

        value_type operator()(argument_type const& s) const
        {
            value_type const h1 ( std::hash<std::string>()(s.first_name) );
            value_type const h2 ( std::hash<std::string>()(s.last_name) );
            return h1 ^ (h2 << 1);
        }
    };
}

int main()
{
    S s;
    s.first_name = "Bender";
    s.last_name =  "Rodriguez";
    std::hash<S> hash_fn;

    std::cout << "hash(s) = " << hash_fn(s) << "\n";
}

答案 1 :(得分:-3)

使用您自己的函数污染任何标准命名空间并不是一个好主意。只需将类放在您自己的命名空间中,您就可以执行任何操作。在您的情况下,只需使用自己的API与标准哈希兼容。此外,从您自己的哈希中调用标准哈希没有问题。