gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 18:20:41 34 4
gpt4 key购买 nike

我正在使用 std::unordered_set第一次对哈希函数有疑问。据我了解,如果您不指定哈希函数,它将默认为 std::hash<Key> .

我有一个 mySet我的一个类(class)的成员:

typedef std::unordered_set<MyClass> USetType;
USetType mySet;

当我尝试构建时,出现以下错误:

error C2440: 'type cast' : cannot convert from 'const MyClass' to 'size_t'

如果要使用size_t,是否需要定义一个转换函数(到unordered_set)使用自定义类?有什么方法可以避免编写自己的哈希函数而只使用默认值吗?

最佳答案

如果您没有指定自己的散列仿函数作为模板参数,它将默认为 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 */
}
};
}

并确保在散列声明之前包含此代码。这样你就可以简单地将散列声明为 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;
}

关于c++ - 自定义类的 unordered_set 是否有默认的哈希函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13485979/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com