unordered_map的hash函数是什么

438 阅读2分钟

C++ 中的 unordered_map 使用了默认的哈希函数,这个哈希函数是由标准库提供的,对于不同类型的键,采用不同的哈希函数。

对于内置类型(如整数、浮点数、指针等),标准库提供了一组预定义的哈希函数,这些哈希函数已经被优化过,通常能够提供较好的性能和均匀的分布。

C++ 标准库中的默认哈希函数通常在头文件 <functional> 中定义,具体的实现可能会因不同的标准库实现而略有差异。以下是一些常见类型的默认哈希函数的简化示例:

对于整数类型(如 intlongsize_t 等):

#include <functional>

std::hash<int> intHash; // 默认的整数哈希函数

int main() {
    int x = 42;
    size_t hashValue = intHash(x); // 计算 x 的哈希值
    return 0;
}

对于字符串类型(如 std::string):

#include <functional>
#include <string>

std::hash<std::string> stringHash; // 默认的字符串哈希函数

int main() {
    std::string str = "hello";
    size_t hashValue = stringHash(str); // 计算字符串 str 的哈希值
    return 0;
}

对于指针类型(如 void*int* 等):

#include <functional>

std::hash<void*> ptrHash; // 默认的指针哈希函数

int main() {
    int value = 42;
    int* ptr = &value;
    size_t hashValue = ptrHash(ptr); // 计算指针 ptr 的哈希值
    return 0;
}

这些是一些常见类型的默认哈希函数的简化示例,具体的实现细节可能会因不同的标准库实现而略有差异。

对于自定义类型,如果要在 unordered_map 中使用,需要提供自定义的哈希函数。一种常见的做法是使用 std::hash 模板类,通过特化或者重载的方式提供对应类型的哈希函数。

例如,假设我们有一个自定义的结构体 Point

struct Point {
    int x;
    int y;
};

我们可以通过特化 std::hash 模板类来提供 Point 类型的哈希函数:

namespace std {
    template <>
    struct hash<Point> {
        size_t operator()(const Point& p) const {
            // 使用内置类型的哈希函数来计算哈希值
            size_t hashX = hash<int>()(p.x);
            size_t hashY = hash<int>()(p.y);
            // 将 x 和 y 的哈希值合并起来
            return hashX ^ (hashY << 1);
        }
    };
}

在这个例子中,我们使用了 std::hash<int>() 来计算 xy 分量的哈希值,并将它们合并起来。需要注意的是,哈希函数应该尽可能地均匀分布键的哈希值,以提高 unordered_map 的性能。

总的来说,unordered_map 的哈希函数可以是标准库提供的预定义函数,也可以是自定义的哈希函数,具体取决于键的类型和开发者的需求。