使用Windows下 RECT 类型做unordered_map 键值
1. Hash 函数
计算自定义类型的hash值。
struct hash_RECT
{
size_t operator()(const RECT &rc) const
{
return std::_Hash_seq((const unsigned char *)&rc, sizeof(RECT));
}
};
2. 相等函数
哈希需要处理碰撞,意味着必须判断两个自定义类型对象是否相等。
struct cmp_RECT
{
bool operator()(const RECT &rc1, const RECT &rc2) const
{
return rc1.left == rc2.left && rc1.top == rc2.top
&& rc1.right == rc2.right && rc1.bottom == rc2.bottom;
}
};
3. 使用
std::unordered_map<RECT, std::wstring, hash_RECT, cmp_RECT> G_mapText
这样感觉好长,我们接着往下看。
4. 使用STL提供的模板
stl中有这么两个模板
// TEMPLATE STRUCT _Bitwise_hash
template<class _Kty>
struct _Bitwise_hash
{ // hash functor for plain old data
typedef _Kty argument_type;
typedef size_t result_type; size_t operator()(const _Kty& _Keyval) const
{ // hash _Keyval to size_t value by pseudorandomizing transform
return (_Hash_seq((const unsigned char *)&_Keyval, sizeof (_Kty)));
}
}; // TEMPLATE STRUCT hash
template<class _Kty>
struct hash
: public _Bitwise_hash<_Kty>
{ // hash functor for enums
static const bool _Value = __is_enum(_Kty);
static_assert(_Value,
"The C++ Standard doesn't provide a hash for this type.");
};
所以我们可以直接这么写:
std::unordered_map<RECT, std::wstring, std::hash<RECT>, cmp_RECT> G_mapText
这样就可以丢掉上面的 hash函数 “hash_RECT” 。
这样写感觉还是比较长,我们再来看看另一种方法。
4. 实例化模板
直接实例化模板,这样的话使用 unordered_map 时便不用再指定 Hash 函数,但要求必须为 KEY 重载 operator ==,实例化模板如下:
namespace std
{
template<>
struct hash<RECT>
: public _Bitwise_hash<RECT>
{ // hash functor for RECT
}; inline bool operator == (const RECT &rc1, const RECT &rc2) _NOEXCEPT
{
return rc1.left == rc2.left && rc1.top == rc2.top
&& rc1.right == rc2.right && rc1.bottom == rc2.bottom;
}
}
这样我们就可以直接这么写了:
std::unordered_map<RECT, std::wstring> G_mapText;
实例代码:
至此 unordered_map 自定义键值的用法结束。