共计 1026 个字符,预计需要花费 3 分钟才能阅读完成。
一句话总结

map 需要重载小于号, unordered_map 需要重载== 比较
map 和 unordered_map 都需要特化 std::hash
std::hash 里面就一个小括号重载, 返回结构计算处理的哈希值
struct MAP_KEY
{
int i; // 结构的成员....
PAINTSTRUCT ps; // 可以是复杂类型
std::vector<int> arr; // 也可以是对象
// 这个是 map 使用, 比较本结构是否比传递进来的结构小
bool operator<(const MAP_KEY& p) const
{
return i < p.i;
}
// 这个是 unordered_map 使用, 比较本结构和传递进来的结构是否是一样
bool operator==(const MAP_KEY& p) const
{
return ps.hdc == p.ps.hdc &&
memcmp(&ps.rcPaint, &p.ps.rcPaint, sizeof(ps.rcPaint)) == 0;
}
};
template <> struct std::hash<MAP_KEY>
{
_NODISCARD size_t operator()(const MAP_KEY& _Keyval) const noexcept
{
// 这里返回结构计算的哈希值, 如果结构是普通类型
// 可以使用 std::_Fnv1a_append_value() 来计算哈希值
//
// 是复杂类型的, 需要自行计算, 比如现在这个结构有vector
// 数组内容可能会增删, 所以不把数组内容加入到计算哈希中
// 这里演示直接 把ps成员 和 i 成员分别计算然后异或
return std::_Fnv1a_append_value(std::_FNV_offset_basis, _Keyval.ps) ^
std::_Fnv1a_append_value(std::_FNV_offset_basis, _Keyval.i);
// 或者 std::is_trivial_v<> 的值是false的时候
// 而且自己知道结构里除了没有默认构造函数之外没有其他东西
// 那可以直接调用 std::_Fnv1a_append_bytes() 来计算
// 直接把本结构的每个字节拿出来计算哈希
return std::_Fnv1a_append_bytes(std::_FNV_offset_basis,
&reinterpret_cast<const unsigned char&>(_Keyval),
sizeof(_Keyval));
}
};
正文完