我问了一个问题Do C++ POD types have RTTI?,有人在评论中告诉我:
POD类型确实有type_info,但没有RTTI,这是可能的 因为type_info并不总是RTTI。
似乎正确,因为我可以获得POD(非多态)类型的type_info
。
但是当我编译这个简单的程序时:
#include <iostream>
struct X
{
int a;
};
int main()
{
using namespace std;
std::cout << typeid(X) << std::endl;
return 0;
}
带有GCC标志-fno-rtti
的:
$ g++ -fno-rtti main.cpp && ./main
它不会编译:
main.cpp: In function ‘int main()’:
main.cpp:12:26: error: cannot use typeid with -fno-rtti
std::cout << typeid(X) << std::endl;
^
这是否意味着type_info
是RTTI的一部分,还是只是GCC的行为?
答案 0 :(得分:4)
RTTI本身并不是真正正式定义的东西:C ++只说明了typeid
和dynamic_cast
的作用,而不是它们是如何实现的。但是,确实很方便的是将这种操作分组为RTTI的通用名称。
请注意,在运行时严格获取此信息需要
。 if ( typeid(int) == typeid(double) )
也可以在项目评估期间确定,就像std::is_same
一样。 int
无可否认是非多态的(它没有'动态'类型)。 cppreference甚至声称:
当应用于多态类型的表达式时,对typeid表达式的求值可能涉及运行时开销(虚拟表查找),否则在编译时解析typeid表达式。
但要小心谨慎。
这是否意味着type_info是RTTI的一部分,还是仅仅是GCC的行为?
type_info
是类。您可能无法构造该类型的任何对象 - 您只能通过typeid
。
-fno-rtti
在GCC下禁用RTTI:您无法使用typeid
,因此也不能type_info
。他们彼此非常亲密。
总而言之,原始报价是完全正确的:
POD类型确实有
type_info
,但没有RTTI,这是可能的,因为type_info并不总是RTTI。
运行时信息可通过typeid
获得。没有什么动态可以考虑(事实上,dynamic_cast
没有任何意义。)
答案 1 :(得分:2)
标准中没有“RTTI”的概念。相反,用不同的词语说。
<typeinfo>
在[support.general]中被称为“动态类型识别”
[intro.object]说:“有些对象是多态(10.3);实现生成与每个这样的对象相关的信息,这使得在程序执行期间可以确定对象的类型“
[expr.dynamic.cast]讨论在“运行时”发生的检查。标准中“运行时”的所有其他用法指的是其他内容。
[expr.typeid]解释了typeid
的作用:
2当
typeid
应用于类型为a的glvalue表达式时 多态类型(10.3),结果是指std::type_info
表示最派生对象类型的对象(1.8)(即 是glvalue所指的动态类型。 ...
后者通常被称为“运行时”操作。
3当
typeid
应用于除了glvalue之外的表达式时 多态类类型,结果引用std::type_info
对象 表示表达式的静态类型。 ......表达式是未评估的操作数(第5条)。
虽然前者可以被视为“编译时”操作。
无论如何,如果你使用typeid
标志,GCC并不真正关心和禁用dynamic_cast
和-fno-rtti
:
if (! flag_rtti)
{
error ("cannot use typeid with -fno-rtti");
return false;
}
是否只能为多态类型禁用typeid
?当然。但是我们将使用occam的剃刀,因为在发展方面更容易阻止完全使用typeid
。