C++ std::type_index用法 _ 在容器中存储类类型信息【详解】

夏强姑娘_1690

夏强姑娘_1690

2026-04-14

731人浏览

原创

std::type_index可安全用作map键,因其可拷贝、支持比较与哈希,而std::type_info&不可用;需开启rtti,注意类型修饰符敏感性、hash_code()非持久化及完整类型要求。

c++ std::type_index用法 _ 在容器中存储类类型信息【详解】

std::type_index 可以安全地作为 std::map 或 std::unordered_map 的键,但必须注意它不自动提供稳定哈希或跨平台可比性,且依赖 RTTI 开启。

为什么不能直接用 std::type_info& 做容器键

因为 std::type_info 禁止拷贝、不可构造、无默认比较语义,也不能存入标准关联/无序容器。你写 std::map<:type_info t></:type_info> 会编译失败;即使绕过(比如用指针),std::type_info::operator== 在某些旧标准下行为未定义,且无法哈希。

而 std::type_index 是专为解决这个问题设计的包装:它可拷贝、可移动、支持 ==/!=、提供 hash_code(),并隐式转换自 const std::type_info&。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • 常见错误现象:std::type_info 引用生命周期短(如临时 typeid(x)),存储其地址会导致悬垂指针
  • 使用场景:工厂注册表、策略映射、插件系统中按类型分发对象
  • 性能影响:std::type_index 内部仅保存指向 std::type_info 的 const 指针,构造和比较都是 O(1);hash_code() 通常也是 O(1),但值不稳定

std::type_index 作 std::unordered_map 键要手动提供哈希器

std::unordered_map 默认用 std::hash<:type_index></:type_index>,C++11 起标准已特化该模板,所以多数编译器下直接可用。但要注意:

  • 若你用的是极老编译器(如 GCC 4.7 之前),需自行定义 std::hash 特化
  • std::type_index::hash_code() 返回值是实现定义的——同一程序多次运行可能不同,不能用于持久化或网络传输
  • 不要把 hash_code() 当作类型唯一 ID 使用;它只适合单次进程内哈希查找
  • 示例:std::unordered_map<:type_index std::function>> handlers;</:type_index> 是合法且高效的

类型修饰符敏感:int 和 const int 是不同键

std::type_index{typeid(int)} 与 std::type_index{typeid(const int)} 不相等,哪怕你传的是 const int x = 42;。这是由 typeid 语义决定的,std::type_index 忠实反映它。

  • 常见错误现象:注册了 std::type_index{typeid(MyClass)},却用 std::type_index{typeid(const MyClass&)} 去查,结果查不到
  • 使用场景:做类型擦除容器(如 any 替代品)时,务必统一约定“注册用值类型,查询也用值类型”
  • 参数差异:对指针类型,typeid(T*) 和 typeid(T) 完全不同;多态识别要用 typeid(*ptr) 或 typeid(obj),而非 typeid(ptr)
  • 兼容性影响:所有主流编译器(GCC/Clang/MSVC)都遵守这一规则,无需条件编译

RTTI 必须开启,否则 typeid 行为未定义

std::type_index 本身不触发 RTTI,但它依赖 typeid 的结果。若编译时加了 -fno-rtti(常见于嵌入式或游戏引擎底层模块),typeid 对多态类型会抛异常或崩溃,对非多态类型虽可能编译通过,但行为不可靠。

  • 常见错误现象:程序在调试版正常,发布版(开了 -fno-rtti)运行到 typeid(x) 就 abort
  • 检查方法:编译时确认没传 -fno-rtti;CMake 中可加 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti")
  • 容易被忽略的地方:头文件里用了 std::type_index,但源文件编译选项不一致,导致链接时符号缺失或运行时异常
  • 前置声明类不能用:class X; 后直接 typeid(X) 是非法的——类型必须有完整定义

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.27

315

14

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2018

7

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5599

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

2805

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

3508

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2485

10

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

319

31

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

2024.01.03

3456

7

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

2025.12.06

286

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习