关于std::type_info指针唯一性及TypeInfo替代实现的技术问询
问题解答
1. 最新C++标准是否保证std::type_info指针的唯一性?
C++标准不保证指向std::type_info对象的指针对于同一类型是唯一的。标准仅要求:同一类型的两个std::type_info对象(比如通过typeid获取)调用operator==会返回true,但它们的内存地址可能不同。这种情况常见于跨动态链接库/共享库的场景——同一类型在不同库中被实例化时,每个库可能生成独立的std::type_info实例,导致指针地址不一致。
2. 实现类型唯一标识的替代方案
如果需要确保每个类型对应全局唯一的标识(不受链接场景影响),可以采用以下几种方案:
方案一:编译期生成唯一ID
利用C++11及以后的模板元编程,为每个类型生成编译期确定的唯一标识:
template<typename T> struct TypeId { static constexpr size_t value = reinterpret_cast<size_t>(&TypeId<T>::value); }; // 使用示例:TypeId<MyClass>::value 即为MyClass的唯一ID
这种方式依赖编译器对模板实例化的处理,同一类型的TypeId<T>::value地址在整个程序(包括跨库场景,只要类型定义一致)中是唯一的。
方案二:运行时注册表分配ID
维护一个全局注册表,首次遇到某类型时分配唯一ID:
#include <unordered_map> #include <typeindex> #include <mutex> class TypeRegistry { public: template<typename T> static size_t getTypeId() { static std::mutex mutex; std::lock_guard<std::mutex> lock(mutex); static std::unordered_map<std::type_index, size_t> idMap; std::type_index idx(typeid(T)); if (!idMap.count(idx)) { idMap[idx] = nextId++; } return idMap[idx]; } private: static size_t nextId; }; size_t TypeRegistry::nextId = 0; // 使用示例:TypeRegistry::getTypeId<MyClass>()
这里用std::type_index(基于std::type_info的相等性判断)作为键,确保即使std::type_info指针不同,同一类型也能映射到同一个ID。
方案三:直接使用std::type_index
C++11引入的std::type_index封装了std::type_info,并重载了哈希和比较运算符,能正确处理std::type_info对象不同但类型相同的情况。可以直接用它作为容器的键,替代原始的std::type_info*:
#include <typeindex> #include <unordered_map> std::unordered_map<std::type_index, void*> factoryMap; // 插入示例: factoryMap[std::type_index(typeid(MyClass))] = &myFactory; // 查询示例: auto it = factoryMap.find(std::type_index(typeid(MyClass)));
内容的提问来源于stack exchange,提问作者user3882729
相关产品推荐
相关产品推荐

