typeid 返回 std::type_info 类型的 const 引用,不可直接打印或字符串比较;常见错误是误用 cout
调用 typeid 得到的是 std::type_info 类型的 const 引用,它不支持直接打印或比较字符串。常见错误是写 cout 期望输出类名,结果却是未定义行为或乱码——因为 std::type_info::name() 返回的是编译器特定的内部符号名(如 "St6vectorIiSaIiEE"),不是可读类型名。
.name() 才能获取 C 风格字符串指针.name() 的返回值生命周期绑定到 type_info 对象,不能长期保存.name() 输出不同(GCC 是 mangled 名,MSVC 可能带空格和修饰)
可能拿到不准确的类型名即使编译时启用了 RTTI(-frtti / /GR),typeid 在多态场景下表现也受对象实际状态影响:
typeid(*ptr) 才能获得动态类型;typeid(ptr) 永远返回指针类型本身(如 "PKi")nullptr,typeid(*ptr) 会抛出 std::bad_typeid 异常typeid 始终返回静态类型,无法反映继承关系中的实际类型class Base {};
class Derived : public Base {};
Base b;
Derived d;
Base* p = &d;
cout << typeid(p).name() << endl; // "P4Base"(指针类型)
cout << typeid(*p).name() << endl; // "4Base"(静态类型,因 Base 无虚函数)要将 typeid(T).name() 转成类似 "std::vector 的形式,必须调用 ABI 特定的 demangling 函数:
abi::__cxa_demangle(),需手动申请内存并释放typeid 的 .name() 默认已 demangle,但含冗余空格和前缀(如 "class std::vector >" )abi::__cxa_demangle 可能返回 nullptr(如输入非法)#includeint status; char* demangled = abi::__cxa_demangle(typeid(std::vector ).name(), 0, 0, &status); if (status == 0) { cout << demangled << endl; // "std::vector >" free(demangled); }
如果目标只是日志、断言或调试输出,typeid 的不可靠性和开销(RTTI 表、虚表查找)让它不如编译期方案:
std::source_location::function_name() + 模板参数推导模拟类型名__PRETTY_FUNCTION__ 或 __FUNCSIG__ 提取类型片段(例如 GCC 中 __PRETTY_FUNCTION__ 包含完整模板实参)真正需要运行时判断类型时,优先考虑虚函数 + dynamic_cast,而不是依赖 typeid().name() 字符串匹配——后者极易因编译器差异或优化级别变化而失效。