typeid用于获取变量运行时类型信息,需包含<typeinfo>头文件;对多态类型才体现运行时特性,其name()返回实现定义的编码名,可用abi::__cxa_demangle解码,类型比较应使用==操作符而非字符串比较。

怎么用 typeid 获取变量的运行时类型信息
typeid 是 C++ RTTI(运行时类型识别)机制的一部分,它在运行时返回一个 std::type_info 对象,可用于比较或查询类型。但要注意:只有带虚函数的类(即多态类型)或使用引用/指针时,typeid 才体现“运行时”特性;对普通变量(如 int x = 5;),它返回的是编译期确定的静态类型。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 对非多态对象(如基本类型、普通 struct),
typeid(x).name()返回的是编译器内部编码名(如"i"表示int),不是可读字符串 - 对多态类指针/引用,
typeid(*ptr)才会真正根据实际所指对象类型返回结果(前提是开启 RTTI,且类有虚函数) - 必须包含头文件
<typeinfo>,否则编译失败 - 若对空指针解引用后用
typeid(如typeid(*nullptr)),行为未定义,会崩溃
typeid().name() 返回的字符串为什么乱码或不可读
std::type_info::name() 的返回值是实现定义的——GCC/Clang 返回 mangled 名(如 "St6vectorIiSaIiEE"),MSVC 也类似。它不是为人类阅读设计的,而是供编译器/链接器内部使用的符号名。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 不要直接打印
typeid(x).name()并期望看到"std::vector<int>"这样的结果 - Linux/macOS 下可用
abi::__cxa_demangle()解析(需<cstdlib>和<cxxabi.h>),但要注意内存管理(返回的 char* 需free()) - Windows 下可用
UnDecorateSymbolName()(dbghelp.h),但仅限于调试符号场景,不推荐用于生产逻辑 - 若只需可读名,更稳妥的做法是手动映射:对已知类型写
if (typeid(x) == typeid(int)) return "int";
判断两个变量是否为同一类型,用 == 比较 typeid 结果即可
std::type_info 重载了 == 和 !=,可用于安全、高效的类型相等判断,比字符串比较更可靠(避免 demangle 失败或平台差异)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 写法:
if (typeid(a) == typeid(b)) { ... }—— 这是合法且推荐的方式 - 注意:
typeid(a) == typeid(const int)与typeid(a) == typeid(int)在 a 是int时都为 true(cv-qualifiers 被忽略) - 对数组类型,
typeid(int[3]) != typeid(int[5]),维度不同则类型不同 - 对模板实例化类型,
typeid(std::vector<int>) != typeid(std::vector<double>),完全独立
不用 typeid 的替代方案:C++17 的 std::is_same_v 和 decltype
如果只是编译期类型判断(比如模板内做 SFINAE 或 static_assert),typeid 完全没必要——它开销大、不可靠,且只能在运行时用。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 编译期判断两个类型是否相同:用
std::is_same_v<decltype(x), int>或std::is_same_v<T, U> - 配合
if constexpr(C++17)做零开销分支:if constexpr (std::is_same_v<T, std::string>) { ... } - 获取表达式类型名用于调试输出?可借助编译器扩展,如 GCC 的
__PRETTY_FUNCTION__,配合字符串截取提取类型部分(虽不标准但实用) - 需要跨平台、可读、运行时类型名?建议封装一层类型注册表,手动关联
std::type_info*到友好字符串
真正容易被忽略的是:RTTI 默认可能被关闭(如 GCC 加了 -fno-rtti),此时 typeid 无法使用,连编译都过不去;而 std::is_same_v 这类编译期工具完全不受影响。如果项目对二进制体积或异常机制敏感,得先确认 RTTI 状态再决定是否依赖 typeid。










