使用unordered_map需包含头文件且编译标准为c++11及以上;声明时常用前两个模板参数;插入推荐emplace()或insert(),查找优先用at()或find();自定义key须提供哈希函数和等价比较;性能优化可调reserve()和max_load_factor()。

unordered_map 基本声明和头文件别漏了
不加 #include <unordered_map></unordered_map> 就直接用 std::unordered_map,编译器会报 error: 'unordered_map' is not a member of 'std'。C++11 起才支持,老项目若用 C++98/03 标准,它根本不存在——得先确认编译器标准(比如 g++ -std=c++11)。
声明时注意模板参数顺序:std::unordered_map<key value hash pred alloc></key>,日常只填前两个就够了:
std::unordered_map<std::string, int> word_count; std::unordered_map<int, std::string> id_to_name;
插入与查找别混用 operator[] 和 at() 的行为差异
operator[] 在键不存在时会**默认构造值并插入**,这可能引发意外副作用(比如对自定义类型调用默认构造函数,或对 int 插入 0);at() 则严格只查找,找不到直接抛 std::out_of_range 异常。
- 要安全读取且不想插入新项 → 用
at()或先查find() - 想“有则更新、无则初始化为 0” →
word_count["hello"]++没问题 - 插入新键值对推荐用
insert()或emplace(),避免operator[]的隐式构造开销
word_count.insert({"world", 1}); // 插入键值对
word_count.emplace("cpp", 5); // 原地构造,更高效
if (word_count.find("test") != word_count.end()) {
std::cout << word_count.at("test"); // 安全访问
}
自定义类型作 key 必须提供哈希函数和等价比较
用 struct 或 class 当 key 时,unordered_map 默认没有哈希规则,编译直接失败:error: no match for call to '(const std::hash<mystruct>) ...'</mystruct>。
立即学习“C++免费学习笔记(深入)”;
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
必须显式提供两样东西:
- 一个可调用对象(函数对象或 lambda)作为哈希函数,满足
size_t operator()(const Key&) const - 一个等价比较谓词(默认是
std::equal_to<key></key>),通常重载operator==就够了
最简方案:特化 std::hash 模板(需在 std 命名空间内):
struct Point { int x, y; };
namespace std {
template<> struct hash<Point> {
size_t operator()(const Point& p) const {
return hash<int>{}(p.x) ^ (hash<int>{}(p.y) << 1);
}
};
}
std::unordered_map<Point, std::string> map;
map[{1,2}] = "origin";
性能陷阱:桶数量、负载因子和 rehash 触发时机
unordered_map 查找平均 O(1),但实际受哈希碰撞和 rehash 影响很大。当 size() / bucket_count()(即负载因子)超过 max_load_factor()(默认 1.0)时,会自动 rehash——重新分配内存、重建所有桶,此时操作变成 O(n)。
高频插入场景下,提前预留空间能避免多次 rehash:
- 知道大概元素数?用
reserve(n)预分配足够桶(不是 reserve 内存,是 reserve 桶数) - 频繁增删导致负载因子剧烈波动?可调
max_load_factor(0.75)换取更稳定性能 - 迭代器失效:rehash 后所有迭代器、引用、指针全部失效(这点和
vector的扩容不同,它连指针都废)
std::unordered_map<int, std::string> cache; cache.reserve(1000); // 预留约 1000 个桶 cache.max_load_factor(0.5); // 更保守的负载上限哈希表不是万能加速器,key 类型的哈希质量、冲突链长度、内存局部性这些底层细节,往往比语法用得熟不熟更能决定实际性能。










