是否有自定义类的unordered_set的默认哈希函数?

use*_*967 7 c++ hash unordered-set

std::unordered_set第一次使用a 并且对哈希函数有疑问.据我所知,如果你没有指定哈希函数,它将默认为std::hash<Key>.

我的一个mySet班级有一名成员:

typedef std::unordered_set<MyClass> USetType;
USetType mySet;
Run Code Online (Sandbox Code Playgroud)

当我尝试构建时,我收到以下错误:

错误C2440:'type cast':无法从'const MyClass'转换为'size_t'

size_t如果要使用unordered_set自定义类,是否需要定义转换函数(to )?有没有办法避免编写自己的哈希函数并只使用默认值?

jog*_*pan 12

如果您没有将自己的散列函数指定为模板参数,那么它将默认为std::hash<MyClass>,除非您定义它,否则它不存在.

最好定义你自己的std::hash内部命名空间的专业化std:

namespace std {
  template <>
  struct hash<MyClass>
  {
    typedef MyClass      argument_type;
    typedef std::size_t  result_type;

    result_type operator()(const MyClass & t) const
    {
       /* ..calculate hash value for t */
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

并确保在声明哈希之前包含此代码.这样,您可以简单地声明哈希,std::unordered_set<MyClass>而无需进一步的模板参数.

您没有指定MyClass内部的内容,但典型情况是您的用户定义类型只包含几个简单类型成员,其中存在默认哈希函数.在这种情况下,您可能希望将各个类型的哈希值组合为整个组合的哈希值.Boost库提供了一个hash_combine为此目的而调用的函数.当然,不能保证它在您的特定情况下能够很好地工作(它取决于数据值的分布和碰撞的可能性),但它提供了一个好的且易于使用的起点.

以下是如何使用它的示例,假设MyClass包含两个字符串成员:

#include <unordered_set>
#include <boost/functional/hash.hpp>

struct MyClass
{
  std::string _s1;
  std::string _s2;
};

namespace std {
  template <>
  struct hash<MyClass>
  {
    typedef MyClass      argument_type;
    typedef std::size_t  result_type;

    result_type operator()(const MyClass & t) const
    {
      std::size_t val { 0 };
      boost::hash_combine(val,t._s1);
      boost::hash_combine(val,t._s2);
      return val;
    }
  };
}

int main()
{
  std::unordered_set<MyClass> s;
  /* ... */
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 专门研究`std :: hash <>`有什么'麻烦'?一个自定义哈希算子将看起来相同的90%... (5认同)
  • @ user974967好吧.如果你将set声明为`std :: unordered_set <MyClass,std :: hash <std :: size_t >>`,它会工作.我想这是一个可能的解决方案,但是它需要定义`operator std :: size_t()`,这可能意味着你会在代码的其他部分得到不希望的隐式转换为整数.我不建议这样做. (2认同)
  • 当然,定义自己的仿函数类当然没问题.(虽然我不同意有关创建`std :: hash`专业化的任何不洁之处.)但我认为你是对的,专门研究`std :: hash`的唯一好处就是你可以使用默认模板那么论证. (2认同)
  • 您还需要重载equal_to(或operator ==) (2认同)