为什么使用std::type_index而不是std::type_info*?

33

我需要按类型在地图上输入一些数据。目前我的代码大致如下:

struct TypeInfoComparer
{
  bool operator()(std::type_info const* a, std::type_info const* b) const
  {
    return a->before(*b);
  };
};

std::map<std::type_info const*, Foo, TypeInfoComparer> d_fooByTypeId;

我可以使用以下方式查找它(例如,在具有<typename T>的模板方法中):

auto pair = d_fooByTypeId.find(&typeid(T));

然而今天我在阅读有关std::type_index的文章,它似乎是为了在这种情况下使用而设计的。

我对提高我的C++知识感兴趣。请问是否应该修改我的代码以使用std::type_index,以及为什么?除了能够删除TypeInfoComparer之外,还有其他原因吗?


1
你认为 typeid 返回的 type_info 对于给定类型是持久且唯一的,这是因为什么原因? - Yakk - Adam Nevraumont
7
@Yakk说:"typeid表达式的结果是一个静态类型为const std::type_info的左值...由该左值所引用对象的生命周期延伸到程序结束。" ([expr.typeid]). 他并没有假设它是唯一的;他在比较器中使用标准的before成员函数。我不知道为什么每个人都忽略了这个事实。 - rici
2个回答

30

type_index是"type_info"的简单包装器,可用作关联容器(23.4)和无序关联容器(23.5)中的索引类型。如果您使用 type_index 而不是 type_info* ,则可以免除在映射中提供显式比较器的麻烦。唯一的代价是您需要#include <typeindex>头文件。

另一个好处是它将允许您切换到(或同时使用)哈希表(也称为unordered_maps)。

总的来说,由于它可以简化代码,我建议您: "试试看吧"。


2
使用map的原因很少,因为before顺序是任意的。 - Yakk - Adam Nevraumont
使用std::type_index和使用std::type_info::hash_code()或者说size_t有什么区别? - Zebrafish
@zebrafish:std::type_index是一种类型的完全排序,其中保证两种不同的类型会产生具有一致顺序的不同值;它可用于有序或无序容器。std::type_info::hash_code()可能会为两种不同的类型返回相同的值,因此它只能用作哈希函数。实际上,这可能没有区别。但那将是一个实现细节。 - rici

6

我认为使用指向typeid(x)返回结果的指针不能保证始终产生相同的结果。特别是在使用共享库时,保证返回相同对象似乎存在问题。对于排序,std::type_info的预期用途是使用before()成员函数。类std::type_index将其封装成更简单的接口。


“我认为使用指向从typeid(x)返回的结果的指针并不能保证始终产生相同的结果”... 嗯,根据规范,每次使用typeid(x)时都保证返回相同的对象。 - Nawaz
3
在同一类型的typeid表达式的所有求值中,不能保证引用相同的std::type_info实例[...]。请参考https://en.cppreference.com/w/cpp/language/typeid中的“注意事项”部分。 - phön
1
@phön:你说得对,我的先前评论是错误的。然而,我保留了我的先前(不正确)的评论,以便其他人不会犯同样的错误。 - Nawaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接