std::type_index可直接作map键,因它可拷贝、重载比较与哈希,而std::type_info不可;需开启RTTI、包含头文件、统一类型修饰(如去引用/const),避免悬垂指针和跨库不一致。

std::type_index 可以直接用作 std::map 或 std::unordered_map 的键,但必须显式构造、统一类型修饰、开启 RTTI,否则查不到、崩溃或编译失败。
为什么 std::map<:type_index t></:type_index> 能编译通过,而 std::map<const std::type_info t></const> 不行
因为 std::type_info 禁止拷贝、无默认构造、不提供 operator,连 <code>std::map<const std::type_info t></const> 都会触发 “use of deleted function”;std::type_index 是专为容器设计的包装:它可拷贝、可移动、重载了 ==/!=、提供 hash_code(),且支持从 const std::type_info& 隐式转换。
常见错误写法:
-
factory[&typeid(int)] = ...——typeid(int)是临时对象,取地址后立即悬垂 -
std::map<decltype int> m;</decltype>——decltype推导出的是引用类型,不可作为键
正确做法始终是:std::type_index{typeid(T)} 或 std::type_index{typeid(obj)},让 type_index 内部保存并管理 const std::type_info* 生命周期。
std::unordered_map<:type_index t></:type_index> 编译失败?检查三件事
报错 “no matching function for call to ‘hash’” 通常不是 bug,而是配置或环境问题:
- 编译标准未设为 C++11 或更高(例如 GCC 用了
-std=c++98) - RTTI 被禁用(
-fno-rtti),导致typeid行为未定义,连带std::type_index构造失败 - 头文件遗漏:
#include <typeindex></typeindex>和#include <typeinfo></typeinfo>缺一不可
验证是否支持哈希:
static_assert(std::is_default_constructible_v<:hash>>);</:hash>
若断言失败,可显式传入哈希器:std::unordered_map<:type_index t std::hash>></:type_index>。GCC/Clang/MSVC 主流版本(2026 年前)均已特化,无需手动补全。
注册和查询时查不到键?大概率是 cv 限定符或引用不匹配
std::type_index 对 const、&、* 完全敏感:
-
std::type_index{typeid(int)}≠std::type_index{typeid(const int)} -
std::type_index{typeid(MyClass)}≠std::type_index{typeid(const MyClass&)} - 对指针变量误用
typeid(ptr)(得到指针类型),而非typeid(*ptr)(得到所指对象类型)
统一约定建议:
- 工厂/策略注册一律用值类型:
std::type_index{typeid(Concrete)} - 查询时也统一用值类型:
std::type_index{typeid(declval<concrete>())}</concrete>或std::type_index{typeid(*ptr)}(前提是ptr是多态类型指针) - 模板函数中避免直接
typeid(T),若T是引用类型,会带修饰;改用typeid(std::remove_reference_t<t>{})</t>
和 std::any 搭配做类型擦除容器时的关键约束
用 std::type_index 管理 std::any 的类型映射表很常见,但有硬性限制:
-
std::any::type()返回const std::type_info&,必须立刻转成std::type_index查表,不能缓存该引用(生命周期短) - 注册键必须与
std::any::type()返回的类型完全一致:存的是std::any{42},其type()是typeid(int),不是typeid(long) - 前置声明类(
class X;)后不能直接typeid(X),必须有完整定义 - 同一类型在不同动态库中生成的
std::type_index哈希值可能不一致 —— 这点最容易被忽略,跨 DLL/so 的类型查找会失效
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











