【问题标题】:Defining a hash function in TR1 unordered_map inside a struct在结构内的 TR1 unordered_map 中定义哈希函数
【发布时间】:2011-03-25 15:21:13
【问题描述】:

根据this,可以像这样在TR1 unordered_map中定义一个相等函数:

#include <tr1/unordered_map>
using namespace std;
using namespace std::tr1;
struct foo{
    ...
    bool operator==(const foo& b) const{
        return ..;
    }
};

unordered_map<foo,int> map;

是否可以用同样的方式定义散列函数?

【问题讨论】:

    标签: c++ hash tr1 unordered-map


    【解决方案1】:

    如果您想更改默认散列(或者,更常见的是,为当前不支持的类型提供散列),您可以为您的键类型提供 std::tr1::hash&lt;T&gt; 的特化:

    namespace std { 
    namespace tr1 { 
        template<>
        struct hash<typename my_key_type> {
            std::size_t operator()(my_key_type const &key) {
                return whatever;
            }
        };
    }
    }
    

    请注意,为用户定义的类型专门化现有模板是罕见的情况之一,您特别被允许namespace std中编写代码。 p>

    【讨论】:

      【解决方案2】:

      unordered_map 类的签名是这样的:

      template<class Key,
          class Ty,
          class Hash = std::hash<Key>,
          class Pred = std::equal_to<Key>,
          class Alloc = std::allocator<std::pair<const Key, Ty> > >
          class unordered_map;
      

      您的示例有效,因为默认 Pred,std::equal_to,默认使用 operator== 检查相等性。编译器会找到您的 foo::operator== 成员函数并使用它。

      std::hash 没有任何会调用类上的成员函数的特化,因此您不能只使用自定义哈希将成员添加到 foo。您将需要专门化 std::hash 。如果您希望它在 foo 上调用成员函数,请继续。你最终会得到这样的结果:

      struct foo
      {
          size_t hash() const
          {
             // hashing method here, return a size_t
          }
      };
      
      namespace std
      {
          // Specialise std::hash for foo.
          template<>
          class hash< foo >
              : public unary_function< foo, size_t >
          {
          public:
              size_t operator()( const foo& f )
              {
                  return f.hash();
              }
          };
      }
      

      【讨论】:

      • 我收到一个警告,它有一个非虚拟析构函数。有什么建议吗?
      • 原来你不需要子类。
      • 请注意,上面不是子类,它是模板特化。非虚拟析构函数警告表明您将其误读为子类。目的不是继承哈希,而是提供针对您的数据类型量身定制的专门实现。
      • 使运算符constoperator()(foo const&amp; f) const ...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 2020-08-23
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多