使用自定义Key类的std::unordered_map编译错误求助
自定义Key类用于std::unordered_map的编译错误解决
问题代码
#include <iostream> #include <unordered_map> using namespace std; class Item { private: std::string m_ItemId; int m_Price; int m_Count; public: Item(std::string id, int price, int count): m_ItemId(id), m_Count(count), m_Price(price){} int getCount() const { return m_Count;} std::string getItemId() const { return m_ItemId;} int getPrice() const { return m_Price;} }; class Key { int m_value; public: Key(int val) :m_value(val){} int getValue() const {return m_value;} }; struct Compare { size_t operator()(const Key& a, const Key& b) const { return a.getValue() < b.getValue(); } }; unordered_map<Key, Item, Compare> getItemList() { unordered_map<Key, Item,Compare> mapOfItems ; mapOfItems.insert(std::make_pair(Key(1), Item("D121",100,2))); mapOfItems.insert(std::make_pair(Key(8), Item("D122",12,5))); mapOfItems.insert(std::make_pair(Key(6), Item("D125",99,3))); mapOfItems.insert(std::make_pair(Key(3), Item("D123",28,6))); mapOfItems.insert(std::make_pair(Key(2), Item("D125",99,3))); return mapOfItems; } int main() { unordered_map<Key, Item, Compare> mp = getItemList(); return 0; }
编译错误
error: static assertion failed: hash function must be invocable with an argument of key type
错误原因
std::unordered_map的模板参数逻辑和std::map完全不同:
std::map的第三个参数是用于排序的比较函数std::unordered_map的第三个参数是用于计算哈希值的哈希函数,第四个参数才是判断键相等的相等谓词
你错误地把用于排序的Compare结构体当作哈希函数传入,同时没有为自定义Key类提供合法的哈希计算逻辑,这直接触发了编译断言错误。
解决方法
需要完成两个核心步骤:
- 为
Key类提供哈希计算函数 - 为
Key类提供相等判断逻辑
修正后的代码
#include <iostream> #include <unordered_map> #include <string> using namespace std; class Item { private: std::string m_ItemId; int m_Price; int m_Count; public: Item(std::string id, int price, int count): m_ItemId(id), m_Count(count), m_Price(price){} int getCount() const { return m_Count;} std::string getItemId() const { return m_ItemId;} int getPrice() const { return m_Price;} }; class Key { int m_value; public: Key(int val) :m_value(val){} int getValue() const {return m_value;} // 重载相等运算符,用于unordered_map判断键是否相同 bool operator==(const Key& other) const { return m_value == other.m_value; } }; // 自定义Key的哈希函数,复用int类型的哈希实现 struct KeyHash { size_t operator()(const Key& k) const { return hash<int>()(k.getValue()); } }; // 如果不想重载operator==,也可以用这个自定义相等谓词作为unordered_map的第四个参数 // struct KeyEqual { // bool operator()(const Key& a, const Key& b) const { // return a.getValue() == b.getValue(); // } // }; unordered_map<Key, Item, KeyHash> getItemList() { unordered_map<Key, Item, KeyHash> mapOfItems ; mapOfItems.insert(std::make_pair(Key(1), Item("D121",100,2))); mapOfItems.insert(std::make_pair(Key(8), Item("D122",12,5))); mapOfItems.insert(std::make_pair(Key(6), Item("D125",99,3))); mapOfItems.insert(std::make_pair(Key(3), Item("D123",28,6))); mapOfItems.insert(std::make_pair(Key(2), Item("D125",99,3))); return mapOfItems; } int main() { unordered_map<Key, Item, KeyHash> mp = getItemList(); // 测试访问元素 auto it = mp.find(Key(1)); if (it != mp.end()) { cout << "Item ID: " << it->second.getItemId() << ", Price: " << it->second.getPrice() << endl; } return 0; }
关键说明
- 哈希函数:
KeyHash结构体实现了对Key的哈希计算,这里直接复用标准库对int的哈希逻辑,因为Key的核心标识是int类型。 - 相等判断:通过重载
Key类的operator==,让std::unordered_map可以判断两个Key是否代表同一个键。如果不想修改Key类,也可以自定义KeyEqual结构体作为unordered_map的第四个模板参数。 - 模板参数修正:将
unordered_map的第三个参数改为自定义哈希函数KeyHash,替换原来错误的Compare结构体。
内容的提问来源于stack exchange,提问作者Ghazi
相关产品推荐
相关产品推荐

