可以比较两个typeid()结果的结果吗? cppreference关于此运算符的注释如下:
不能保证将相同的std :: type_info实例 同一类型上所有typeid表达式的求值所引用 类型,尽管这些type_info对象的std :: type_info :: hash_code 会和它们的std :: type_index一样。
const std::type_info& ti1 = typeid(A);
const std::type_info& ti2 = typeid(A);
assert(&ti1 == &ti2); // not guaranteed
assert(ti1.hash_code() == ti2.hash_code()); // guaranteed
assert(std::type_index(ti1) == std::type_index(ti2)); // guaranteed
我的理解是,返回值是对type_info类型的静态L值的引用。这就是说&ti1 ==&ti2对于相同类型不保证是相同的。相反,它说使用哈希码或std :: type_index类。但是,它没有提及是否直接比较类型:
ti1 == ti2;
保证是正确的。我以前用过,文档是否暗含了保证?
答案 0 :(得分:5)
std::type_info
是类类型,这意味着ti1 == ti2
表达式将触发重载的operator==
。其行为由[type.info]/p2描述:
bool operator==(const type_info& rhs) const noexcept;
效果:将当前对象与
rhs
进行比较。返回:
true
,如果两个值描述的是相同类型。
答案 1 :(得分:0)
一些有关实现的信息可能是令人感兴趣的:对于g ++ / clang,type_info以两个指针开头。第二个指向固定的字符串,即name()返回的值。
**请注意,该实现不是标准要求的,并且对于同一编译器,不同目标之间可能会有所不同。
首先通过检查type_info是否在同一地址来进行比较。如果是这样,它们是相等的;如果不是,则接下来对两个“名称”字符串调用strcmp()。然后strcmp结果确定.before()
方法的顺序(并扩展为type_index
的顺序)。
通常,对于任何给定类型,程序中只有一个type_info。但是,当使用共享库时,最终可能会在共享库中找到一个,而在其他地方找到另一个。因此,比较地址不足以测试两个type_info是否表示同一类型,也不能将该地址用于排序。 如果存在两个相同类型的type_info,则它们的name()将返回等效的字符串,但是这些字符串将位于不同的地址,因为字符串常量和type_info是一起生成的。
.hash_code()
方法令人失望:它调用一个函数来逐字符地对name()
字符串进行哈希处理。 g ++版本调用strlen
来查找其len,然后调用与std :: hash(std :: string)相同的函数。即使类型未知,也会发生这种情况,例如typeid(std::complex<float>).hash_code()
-原则上,编译器可以在编译时计算结果。
在我的x86_64 clang ++-9.0安装中,我看到一个奇怪的结果-hash_code()返回与name()相同的东西,但转换为size_t。这通常会起作用,但是在程序中存在两个相同类型的type_info的情况下将失败。而且,它不是一个非常丰富的哈希,请考虑出现在64位地址空间内的值的范围。我的安装很可能以某种方式获取了错误的头文件,这就是结果,但是在其他情况下,它似乎可以正常运行。也许这是一个实际的缺陷,没有人使用hash_code(),因为它太慢了...
我为RISC处理器尝试了另一种clang-9,它与g ++的hash_code()类似,但不需要调用strlen。