信息不是RTTI的一部分?
我曾问过一个问题C ++ POD类型是否有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的行为?
抽象
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
将毫无意义)。
标准中没有“RTTI”的概念。 相反,用不同的话来说。
<typeinfo>
在[support.general]中被称为“动态类型标识”
[intro.object]说:“一些对象是多态的(10.3);实现生成与每个这样的对象相关的信息,使得可以在程序执行期间确定该对象的类型”
[expr.dynamic.cast]谈论在“运行时”发生的检查。 标准中“运行时”的所有其他用途都指向其他内容。
[expr.typeid]解释了typeid
作用:
2当typeid
应用于类型为多态类类型(10.3)的glvalue表达式时,结果引用std::type_info
对象,该对象表示最大派生对象(1.8)(即动态类型)的类型这是glvalue所指的。 ...
后者通常称为“运行时”操作。
3当typeid
应用于除多态类类型的glvalue以外的表达式时,结果引用表示表达式的静态类型的std::type_info
对象。 ...表达式是未评估的操作数(第5章)。
前者可被视为“编译时”操作。
无论如何,如果您使用-fno-rtti
标志,GCC并不真正关心和禁用typeid
和dynamic_cast
:
rtti.c:
if (! flag_rtti)
{
error ("cannot use typeid with -fno-rtti");
return false;
}
是否它只能禁用多态类型的typeid
? 当然。 但是我们打算使用occam的剃须刀,因为在整体上防止typeid
的使用在开发上更为简单。
下一篇: Binding to arbitrarily deep properties on an object based on rules