比较来自 typeid() 运算符的两个 type_info
Comparing two type_info from typeid() operator
可以比较两个typeid()结果的结果吗? cppreference 有关于此运算符的注释:
There is no guarantee that the same std::type_info instance will be
referred to by all evaluations of the typeid expression on the same
type, although std::type_info::hash_code of those type_info objects
would be identical, as would be their 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
我的理解是 return 是对类型 type_info 的静态 L 值的引用。它说 &ti1 == &ti2 不能保证相同类型相同。它反而说使用哈希码或 std::type_index class。但是它没有提到是否直接比较类型:
ti1 == ti2;
保证真实。我以前用过这个,文档是否暗示这是有保证的?
std::type_info
is a class-type, which means that the ti1 == ti2
expression will trigger an overloaded operator==
. Its behavior is described by [type.info]/p2:
bool operator==(const type_info& rhs) const noexcept;
Effects: Compares the current object with rhs
.
Returns: true
if the two values describe the same type.
有关实现的一些信息可能很有趣:对于 g++/clang,type_info 以两个指针开头。第二个指向一个固定的字符串,就是name()return编辑的值
** 请注意,此实现不是标准所要求的,并且可能因同一编译器的不同目标而异。
比较是通过首先检查 type_info 是否在同一地址来完成的;如果是这样,他们是平等的;如果不是,接下来在两个 'name' 字符串上调用 strcmp()。并且 strcmp 结果决定了 .before()
方法的顺序(以及 type_index
的顺序)。
通常,对于任何给定的类型,程序中只有一个 type_info。但是,当使用共享库时,有可能在共享库中有一个,而另一个在其他地方。所以,地址的比较不足以判断两个type_info是否代表同一类型,地址也不能用于排序。
如果同一类型存在两个 type_info,它们的 name() 将 return 等效的字符串,但这些字符串将位于不同的地址,因为字符串常量和 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() returns 与 name() 相同,但转换为size_t。这通常会起作用,但在程序中存在两个相同类型的 type_info 的情况下会失败。此外,它不是一个非常丰富的散列,考虑在 64 位地址 space 中出现的值范围。可能是我的安装以某种方式获取了错误的头文件,这就是结果,但它似乎工作正常。也许这是一个实际的缺陷,没有人使用 hash_code() 因为它太慢了......
我为 RISC 处理器尝试了另一个 clang-9,它类似于 hash_code() 的 g++,但不需要调用 strlen。
可以比较两个typeid()结果的结果吗? cppreference 有关于此运算符的注释:
There is no guarantee that the same std::type_info instance will be referred to by all evaluations of the typeid expression on the same type, although std::type_info::hash_code of those type_info objects would be identical, as would be their 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
我的理解是 return 是对类型 type_info 的静态 L 值的引用。它说 &ti1 == &ti2 不能保证相同类型相同。它反而说使用哈希码或 std::type_index class。但是它没有提到是否直接比较类型:
ti1 == ti2;
保证真实。我以前用过这个,文档是否暗示这是有保证的?
std::type_info
is a class-type, which means that the ti1 == ti2
expression will trigger an overloaded operator==
. Its behavior is described by [type.info]/p2:
bool operator==(const type_info& rhs) const noexcept;
Effects: Compares the current object with
rhs
.Returns:
true
if the two values describe the same type.
有关实现的一些信息可能很有趣:对于 g++/clang,type_info 以两个指针开头。第二个指向一个固定的字符串,就是name()return编辑的值
** 请注意,此实现不是标准所要求的,并且可能因同一编译器的不同目标而异。
比较是通过首先检查 type_info 是否在同一地址来完成的;如果是这样,他们是平等的;如果不是,接下来在两个 'name' 字符串上调用 strcmp()。并且 strcmp 结果决定了 .before()
方法的顺序(以及 type_index
的顺序)。
通常,对于任何给定的类型,程序中只有一个 type_info。但是,当使用共享库时,有可能在共享库中有一个,而另一个在其他地方。所以,地址的比较不足以判断两个type_info是否代表同一类型,地址也不能用于排序。 如果同一类型存在两个 type_info,它们的 name() 将 return 等效的字符串,但这些字符串将位于不同的地址,因为字符串常量和 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() returns 与 name() 相同,但转换为size_t。这通常会起作用,但在程序中存在两个相同类型的 type_info 的情况下会失败。此外,它不是一个非常丰富的散列,考虑在 64 位地址 space 中出现的值范围。可能是我的安装以某种方式获取了错误的头文件,这就是结果,但它似乎工作正常。也许这是一个实际的缺陷,没有人使用 hash_code() 因为它太慢了......
我为 RISC 处理器尝试了另一个 clang-9,它类似于 hash_code() 的 g++,但不需要调用 strlen。