为何std::unordered_map无法使用const std::string作为键?
const std::string作为std::unordered_map的键会编译失败? 这个问题的核心和C++标准库对std::unordered_map的哈希函数要求直接相关,咱们一步步拆解原因:
标准哈希函数不支持带
const限定的键类型std::unordered_map依赖std::hash模板生成键的哈希值,但C++标准只给非const的基础类型、标准库类型(比如std::string)提供了std::hash的特化版本。当你把键类型设为const std::string时,编译器找不到对应的std::hash<const std::string>特化实现,自然会抛出编译错误。std::unordered_map本身就会保证键的不可修改性
其实你完全没必要给键类型额外加const——std::unordered_map内部存储的键本身就是不可修改的。它的value_type是std::pair<const K, V>,也就是说,哪怕你声明的是std::unordered_map<std::string, int*>,实际存储的键也是const std::string,根本无法被修改。额外给键类型加const属于画蛇添足,反而触发了哈希函数缺失的问题。
对应你的代码验证
你给出的代码中,把const std::string改成std::string后,编译器能找到标准提供的std::hash<std::string>特化,所以编译顺利通过。如果非要用const std::string作为键(完全不推荐这么做),你需要手动提供哈希函数,比如:
#include <unordered_map> #include <utility> #include <string> #include <iostream> // 自定义const std::string的哈希函数特化 namespace std { template<> struct hash<const std::string> { size_t operator()(const std::string& s) const { return hash<std::string>()(s); } }; } int main() { int myint = 5; std::unordered_map<const std::string, int*> map; map.insert({"string", &myint}); std::cout << *map.at("string") << std::endl; return 0; }
不过再次强调,这种做法没有任何实际意义,因为std::unordered_map已经替你保证了键的不可修改性。
内容的提问来源于stack exchange,提问作者user2138149

