type_info不是RTTI的一部分吗?

时间:2016-06-08 09:55:14

标签: c++ gcc rtti

我问了一个问题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的行为

2 个答案:

答案 0 :(得分:4)

摘要

RTTI本身并不是真正正式定义的东西:C ++只说明了typeiddynamic_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

rtti.c

  if (! flag_rtti)
    {
      error ("cannot use typeid with -fno-rtti");
      return false;
    }

是否只能为多态类型禁用typeid?当然。但是我们将使用occam的剃刀,因为在发展方面更容易阻止完全使用typeid