用哈希函数实现一个key的特化

在自定义类中写哈希函数老是记不住,所以这次我特意举一个简单的例子:
写一个很简单的类,然后用哈希函数实现一个key的特化,以保证这个结构体可以被unordered_map或unordered_set用作key值。
代码如下:

#include <iostream>
#include <unordered_set>

using namespace std;
struct Score
{
    int Chinese;
    int math;

    bool operator== (const Score& others) const
    {
        return tie(Chinese, math) == tie(others.Chinese, others.math);
    }
};

namespace std
{
    template<>
    struct hash<Score>
    {
        size_t operator()(const Score& s) const
        {
            return hash<int>()(s.Chinese) ^ hash<int>()(s.math);
        }
    };
}

int main()
{
    unordered_set<Score> set_Score;
    set_Score.insert({0,0});
    cout << "set_Score.size() is " << set_Score.size() << endl;
    return 0;
}

程序输出是:

set_Score.size() is 1

上述代码是模板特化的示例,它为 std::hash 模板显式地提供了实现。接下来逐行解释下。

namespace std
{

这行代码将后面的代码放在 std 命名空间中。因为标准库中的模板都是写在 std 命名空间中的,如 std::hash 模板。如果你想对标准库中的模板进行特化,那么你必须在同一个命名空间中定义你的模板特化。否则,编译器将无法找到你的模板特化,并会使用标准库中默认的模板实现。

template<>
    struct hash<Score>

这2行代码显式地对 std::hash 模板进行特化。这意味着,当编译器遇到 std::hash 时,它将使用你提供的显式模板特化实现,而不会使用默认的模板实现。

size_t operator()(const Score& s) const

这行代码定义了 std::hash 模板特化的哈希函数。哈希函数接受一个 Score 对象作为参数,并返回一个 size_t 类型的值。

return hash<int>()(s.Chinese) ^ hash<int>()(s.math);

这行代码是哈希函数的具体实现。它将 Score 对象的 Chinese 和 math 字段组合起来作为哈希值。

哈希函数的实现细节如下:

hash()(s.Chinese): 使用默认的整数哈希函数对 s.Chinese 字段进行哈希计算。
hash()(s.math): 使用默认的整数哈希函数对 s.math 字段进行哈希计算。
^: 使用异或运算符将两个哈希值组合起来。
组合后的哈希值是一个 size_t 类型的整数,它可以被 unordered_map 和 unordered_set 用作键值。

因此,这段代码的作用是为 Score 对象提供了一个哈希函数,使 Score 对象可以被 unordered_map 和 unordered_set 用作键值。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码到程攻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值