C++ 中的 unordered_map 使用了默认的哈希函数,这个哈希函数是由标准库提供的,对于不同类型的键,采用不同的哈希函数。
对于内置类型(如整数、浮点数、指针等),标准库提供了一组预定义的哈希函数,这些哈希函数已经被优化过,通常能够提供较好的性能和均匀的分布。
C++ 标准库中的默认哈希函数通常在头文件 <functional> 中定义,具体的实现可能会因不同的标准库实现而略有差异。以下是一些常见类型的默认哈希函数的简化示例:
对于整数类型(如 int、long、size_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>() 来计算 x 和 y 分量的哈希值,并将它们合并起来。需要注意的是,哈希函数应该尽可能地均匀分布键的哈希值,以提高 unordered_map 的性能。
总的来说,unordered_map 的哈希函数可以是标准库提供的预定义函数,也可以是自定义的哈希函数,具体取决于键的类型和开发者的需求。