c++的std::type_index和typeid有什么关系? (运行时类型识别)

std::type_index是typeid返回值的可拷贝、可哈希包装器,仅支持以typeid(…)显式构造,不提供默认或裸指针构造,其比较与哈希依赖底层type_info实现。

c++的std::type_index和typeid有什么关系? (运行时类型识别)

std::type_index 是 typeid 返回值的包装器

typeid 表达式在运行时返回一个 const std::type_info&,它不可拷贝、不可赋值,也不能直接用作容器键或 unordered 容器的哈希目标。std::type_index 就是为解决这个问题而设计的:它内部持有一个 const std::type_info*,并提供了拷贝、比较、哈希等操作符重载。

必须用 typeid(…) 构造 std::type_index,不能直接 new 或默认构造

std::type_index 没有默认构造函数,也不接受裸指针构造。它只接受 typeid 表达式作为参数:

std::type_index ti1 = typeid(int);
std::type_index ti2 = typeid(std::string);
// ✅ 正确:传入 typeid 结果

std::type_index ti3(typeid(double)); // 也合法,显式构造 // ❌ 错误:std::type_index ti; // 编译失败 // ❌ 错误:std::type_index ti(*some_type_info_ptr); // 没有该构造函数

比较和哈希行为完全依赖 underlying type_info 的实现

std::type_index==std::hash<:type_index> 都转发给其内部持有的 type_info 对象。这意味着:

  • 两个 std::type_index 相等 ⇔ 它们封装的 type_info 指向同一类型(包括 cv 限定和引用修饰)
  • std::type_index 可安全用作 std::mapstd::unordered_map 的 key
  • 但注意:typeid(int)typeid(const int) 是不同 type_info,因此 std::type_index 也不同
  • 某些编译器(如 GCC)对模板实例化类型可能生成多个 type_info 地址(尤其跨 DSO 边界),此时 == 可能失效 —— 这不是 std::type_index 的问题,而是 typeid 本身的 ABI 限制

实际用途:替代裸 type_info 做类型注册与分发

最常见的使用场景是构建运行时类型映射表,比如插件系统或序列化框架中按类型查找处理函数:

AI发型设计

AI发型设计

虚拟发型试穿工具和发型模拟器

下载

立即学习C++免费学习笔记(深入)”;

std::unordered_map> handlers;
handlers[typeid(int)] = [](void* p) { std::cout << *static_cast(p) << '/n'; };
handlers[typeid(std::string)] = [](void* p) { std::cout << *static_cast(p) << '/n'; };

// 后续可安全调用: void dispatch(const std::type_info& ti, void* ptr) { auto it = handlers.find(std::type_index(ti)); if (it != handlers.end()) it->second(ptr); }

这里必须用 std::type_index 才能放进 std::unordered_map;若直接存 const std::type_info&,不仅无法哈希,生命周期也难以管理。

真正容易被忽略的是:哪怕你只在单个 .cpp 文件里用 typeid,只要涉及跨编译单元取地址(比如把 &typeid(T) 存进全局 map),就可能撞上 ABI 不一致问题 —— 此时 std::type_index 不会帮你绕过,它只是让 type_info 更好用,而不是更可靠。

https://www.php.cn/faq/1971936.html

发表回复

Your email address will not be published. Required fields are marked *