找回密码
 register
搜索
查看: 10|回复: 0

[文档笔记] MSVC 14.51 为什么删除 <hash_map>?一段跨越 30 年的 STL 往事

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:568
  • 打卡月天数:4
  • 打卡总奖励:565
  • 最近打卡:2026-08-05 07:47:00
Waylee 发表于 2026-8-1 01:29 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

MSVC 14.51 把 <hash_map><hash_set> 文件删掉了。它不是一次突然的标准库破坏,而是一笔拖了约 30 年、正式警告了 10 年的技术债。

这段历史大致是:

  1. C++98 没有哈希容器

    早期标准库只有基于有序树的 std::map / std::set。哈希表曾在 1995 年被提议加入标准,但因为标准制定时间不足而被搁置。

  2. 各家厂商自行补齐

    SGI STL、Dinkumware、Metrowerks 等分别提供了自己的:

    hash_map
    hash_set

    但这些实现的接口并不完全一致。Microsoft 的版本最终位于:

    #include <hash_map>
    stdext::hash_map<Key, Value>

    注意它一直是 Microsoft 扩展,不是 std::hash_map,更不是 ISO C++ 标准的一部分。

  3. 标准故意选择了 unordered_map 这个新名字

    2003 年的 WG21 提案 N1456 解释得很有意思:委员会原本也考虑沿用 hash_map,但当时各厂商已经存在大量“名字相同、接口略有不同”的实现。

    如果标准也叫 hash_map,用户会分不清自己使用的是厂商扩展还是标准版本,厂商也很难保证兼容。因此委员会选择了:

    std::unordered_map
    std::unordered_set

    “unordered” 还直接表达了它与 std::map 最重要的区别:没有按键排序的保证。

  4. C++11 正式接管

    C++11 标准化了 <unordered_map><unordered_set>。从此 <hash_map> 就成为一个历史兼容层,没有继续存在的标准化理由。

  5. VS 2015 开始最后通牒

    从 VS 2015 开始,包含 <hash_map> 默认就会触发硬错误:

    <hash_map> is deprecated and will be REMOVED.
    Please use <unordered_map>.

    当时还可以定义:

    _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS

    绕过错误。这个宏名叫“silence warnings”,实际上绕过的是 #error,属于非常强烈的迁移通知。

  6. 十年后终于执行

    2025 年 10 月,MSVC STL 维护者 Stephan T. Lavavej 提交了 PR #5764,说明原话是:

    With 10 years of notice, it's finally time to deliver as promised.

    该修改删除了约 850 行 <hash_map> / <hash_set> 实现,以及大量 TR1 和兼容性测试,随后进入 MSVC Build Tools 14.51

为什么非删不可?

除了“不属于标准”,官方给出的实际工程原因还有:

  • 阻止新代码继续绑定 MSVC 专有扩展;
  • 减少复杂 STL 内部实现中的特殊分支;
  • 减少测试、修复和新特性适配负担;
  • 让维护者更容易判断标准容器代码是否正确;
  • 旧接口已经有十年的明确迁移窗口。

所以这不是因为 hash_map 这种数据结构过时了。哈希表当然还在,只是标准版本叫 std::unordered_map

一般迁移为:

// 旧代码
#include <hash_map>
stdext::hash_map<int, Widget> values;

// 新代码
#include <unordered_map>
std::unordered_map<int, Widget> values;

但如果旧代码传入了 stdext::hash_compare 或自定义第三模板参数,就不能只做文本替换。hash_map 把哈希和比较策略揉在一个 traits 类型里,而 unordered_map 将它们拆成 HashKeyEqual 两个模板参数,需要分别迁移。MSVC 14.51 中旧文件已经不存在,因此以前那个 _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS 宏也救不了了。

您需要登录后才可以回帖 登录 | register

本版积分规则

QQ|手机版|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-8-5 13:40 , Processed in 0.103385 second(s), 29 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表