【问题标题】:Declaring hash function for unordered_set in c++? [duplicate]在 C++ 中为 unordered_set 声明哈希函数? [复制]
【发布时间】:2012-08-01 22:18:29
【问题描述】:

对于一个相当大的项目,我必须使用 unordered_set,为了确保我正确使用它,我尝试了一个小例子。

#include <iostream>
#include <unordered_set>
using namespace std;

class Foo {
  private:
    int x;
  public:
    Foo(int in) {x = in;}
    bool operator==(const Foo& foo) const {return x == foo.x;}
    size_t hash(const Foo& foo) const {return x;}
};

int main() {
  Foo f1(3);
  unordered_set<Foo> s;
  s.insert(f1);
  return 0;
}

当我编译时,我得到:

/tmp/cc3KFIf4.o: In function `std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(Foo const&) const':
hashset.cc:(.text._ZNKSt8__detail15_Hash_code_baseI3FooS1_St9_IdentityIS1_ESt8equal_toIS1_ESt4hashIS1_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE12_M_hash_codeERKS1_[std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(Foo const&) const]+0x19): undefined reference to `std::hash<Foo>::operator()(Foo) const'
/tmp/cc3KFIf4.o: In function `std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(std::__detail::_Hash_node<Foo, false> const*, unsigned int) const':
hashset.cc:(.text._ZNKSt8__detail15_Hash_code_baseI3FooS1_St9_IdentityIS1_ESt8equal_toIS1_ESt4hashIS1_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE15_M_bucket_indexEPKNS_10_Hash_nodeIS1_Lb0EEEj[std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(std::__detail::_Hash_node<Foo, false> const*, unsigned int) const]+0x28): undefined reference to `std::hash<Foo>::operator()(Foo) const'
collect2: ld returned 1 exit status

它似乎没有看到我的哈希函数,但我认为“哈希”是默认函数名称。我是否正确定义了哈希?还是我需要显式声明一个单独的哈希类作为第二个模板参数?

【问题讨论】:

  • 哈希功能作为额外的模板参数传递。你需要(最好)一个仿函数并做unordered_set&lt;Foo, FooHasher&gt; s(FooHasher());

标签: c++ hash unordered-set


【解决方案1】:

作为 Xeo 在 cmets 中建议的替代方案,您可以在实例化 unordered_set 之前为 std::hash 提供专业化。

namespace std {
    template <>
    struct hash<Foo> {
        size_t operator () (const Foo &f) const { return f.hash(f); }
    };
}

hash 方法的 foo 参数对我来说似乎无关紧要,但我对您提供的接口实现了专门化。

【讨论】:

  • 好的,谢谢,成功了。我实际上并没有让我的哈希函数采用额外的参数,这是一个错字。它应该是 size_t hash() const {return x;} 我唯一感到困惑的是,为什么我不能像使用 operator==() 那样创建一个 hash()?对于 operator== 我不需要做任何额外的事情。
  • @user1575106:不同的 API 会有不同的要求。标准编写者不能满足每个人的愿望,而给定的接口使得在不修改类的情况下尝试不同的哈希算法变得容易。
猜你喜欢
  • 2013-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
相关资源
最近更新 更多