C++ 为c+中的无序#u集声明哈希函数+;?

C++ 为c+中的无序#u集声明哈希函数+;?,c++,hash,unordered-set,C++,Hash,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 == f

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

#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;
}
#包括
#包括
使用名称空间std;
福班{
私人:
int x;
公众:
Foo(int-in){x=in;}
bool运算符==(const Foo&Foo)const{return x==Foo.x;}
大小\u t散列(const Foo&Foo)const{return x;}
};
int main(){
Foo f1(3);
无序的集合;
s、 插入(f1);
返回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
/tmp/cc3KFIf4.o:在函数“std:”中,详细信息::“哈希代码”基::“哈希代码(Foo const&)const”:
hashset.cc:(.text.ZNKSt8_udetail15_Hash_code_baseI3FooS1_St9_identitys1_est8; eSt8_等同于1_ESt4hashIS1_ENS_18_Mod_range_hashinges_20_Default_ranged_hashELb0EE12_M_Hash_Hash_code_coderks1[std:u detaily:u Hash_udetaily:u Hash_code_base::::u Hash_uhash_uhash_code_ubase:::::u Hash_uhash_uhash_uhash_u
/tmp/cc3KFIf4.o:在函数“std::u详细信息::Hash代码base::bucket_index(std:uu详细信息::Hash_Nodeconst*,unsigned int)const”中:
hashset.cc:(.text.ZNKSt8_udetail15_Hash_code_baseI3FooS1_St9_identity1_est8; 8_est8; 1_ESt4hashIS1_en_18_Mod_range_hashinges_20_Default_ranged_hashELb0EE15_M_bucket_indexpkns_10_Hash_nodeIS1_Lb0EEEj[std:u details:u details:u Hash_ude:u details:u Hash_ude:u de:u de:u de:u Hash代码_ubase:u base:u details:u de:u:对“std::hash::operator()(Foo)const”的未定义引用
collect2:ld返回了1个退出状态

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

作为Xeo在注释中建议的替代方案,您可以在实例化
无序集之前为
std::hash
提供专门化

namespace std {
    template <>
    struct hash<Foo> {
        size_t operator () (const Foo &f) const { return f.hash(f); }
    };
}
名称空间std{
模板
结构散列{
size_t运算符()(const Foo&f)const{return f.hash(f);}
};
}

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

hash功能作为额外的模板参数传递。您需要(最好)一个函子和do
unordered_集s(FooHasher())好的,谢谢,成功了。实际上,我没有让我的哈希函数接受一个额外的参数,这是一个输入错误。它应该是size_t hash()const{return x;}唯一让我感到困惑的是,为什么我不能像使用操作符==()那样创建一个hash()?For operator==我不需要做任何额外的事情。@user1575106:不同的API将有不同的要求。标准编写者无法满足每个人的需求,并且给定的接口使得在不修改类的情况下尝试不同的哈希算法变得很容易。