C++中unordered_map数据类型添加自定义Struct作为Key
最近在工作中,遇到了要将定义的变量使用自定义的作为key,然后使用int作为value,遇到了一些问题,下面做个简单的总结。
前提
最近在工作中,遇到了要将unordered_map
定义的变量使用自定义的结构体作为key
,然后使用int
作为value
,遇到了一些问题,下面做个简单的总结。
问题复现
先看下面这段代码:
#include <iostream>
#include <unordered_map>
#include <cstdint>
#include <string>
struct RegInfo{
uint32_t addr;
std::string name;
};
int main()
{
std::unordered_map<RegInfo, int> reg_map;
return 0;
}
我们这里自定义了一个结构体RegInfo
,然后利用这个结构体声明了一个unordered_map
的变量,你可以尝试编译这个程序,会直接报错。报错内容大概如下:
重要的是error后面的信息*use of deleted function ‘std::unordered_map<_Key,_Tp, _Hash,_Pred, _Alloc>…’*巴拉巴拉一大堆的信息。
解决方案
所以unordered_map
这种数据类型是如何定义的。
通过模板进行定义的,Key
和T
我们都明白,代表了Key
和Value
的类型。那么Hash
是什么,在我们不指定它时,它有一个默认参数std::hash<Key>
。KeyEqual
从字面理解好像是判断Key
是否相等,也有一个默认参数std::equal_to<Key>
。
这里的hash到底是在干什么呢?
答:unordered_map
在c++中底层主要是基于哈希表(Hash Table)实现的,通过哈希函数将Key
进行映射到数组索引上,从而实现对Key-Value
的快速查找、插入、删除。它的查询效率和增删效率都是O(1)。unordered_map
会使用用户指定或者默认的Hash
类型(如std::hash<Key>
)计算Key
的哈希值。 好吧,结论出来了,我们没有指定Hash
这个变量,因此它使用默认值std::hash<RegInfo>
,但是没有std::hash<RegInfo>
这个哈希函数,所以报错了。
那我们自己添加一个哈希函数吧,关于如何写哈希函数,可以参考这个网页。修改代码如下:
#include <iostream>
#include <unordered_map>
#include <cstdint>
#include <string>
struct RegInfo{
uint32_t addr;
std::string name;
};
struct KeyHash{ /* 自定义哈希函数 */
size_t operator()(const RegInfo& key) const noexcept
{
size_t h1 = std::hash<uint32_t>{}(key.addr);
size_t h2 = std::hash<std::string>{}(key.name);
return h1 ^ (h2 << 1); /* key 对应的哈希值 */
}
};
int main()
{
std::unordered_map<RegInfo, int, KeyHash> reg_map;
return 0;
}
编译运行,可以通过。那么所有事情就结束了嘛?我们给定义的reg_map
变量添加两个元素看看。添加如下几行代码:
int main()
{
std::unordered_map<RegInfo, int, KeyHash> reg_map;
RegInfo reg1{1, "reg1"};
RegInfo reg2{2, "reg2"};
reg_map[reg1] = 1;
reg_map[reg2] = 2;
return 0;
}
不出意外地出了意外,又报错了。报错信息如下:
这次的报错内容看起来就简单了许多,意思就是对于const RegInfo
类型没有匹配的==
运算符。那我们给它加上==
运算符试试(运算符重载)。
如下代码所示:
struct RegInfo{
uint32_t addr;
std::string name;
bool operator==(const RegInfo& cmp) const
{
return (addr == cmp.addr) && (name == cmp.name);
}
};
我们重载了==
运算符,来判断两个RegInfo
类型的变量是否相等。编译,运行,没有报错。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)