【发布时间】:2010-05-20 19:41:29
【问题描述】:
我想检查 typeid 在与类型名称(即 typeid(int)、typeid(std::string)...)一起使用时在编译时进行评估。
为此,我在一个循环中重复了两个 typeid 调用的比较,并在启用优化的情况下对其进行编译,以查看编译器是否简化了循环(通过查看执行时间是 1us,而当它简化时160 毫秒,而不是)。
我得到了奇怪的结果,因为有时编译器简化了代码,有时却没有。我使用g++(我尝试了不同的4.x版本),程序如下:
#include <iostream>
#include <typeinfo>
#include <time.h>
class DisplayData {};
class RobotDisplay: public DisplayData {};
class SensorDisplay: public DisplayData {};
class RobotQt {};
class SensorQt {};
timespec tp1, tp2;
const int n = 1000000000;
int main()
{
int avg = 0;
clock_gettime(CLOCK_REALTIME, &tp1);
for(int i = 0; i < n; ++i)
{
// if (typeid(RobotQt) == typeid(RobotDisplay)) // (1) compile time
// if (typeid(SensorQt) == typeid(SensorDisplay)) // (2) compile time
if (typeid(RobotQt) == typeid(RobotDisplay) ||
typeid(SensorQt) == typeid(SensorDisplay)) // (3) not compile time ???!!!
avg++;
else
avg--;
}
clock_gettime(CLOCK_REALTIME, &tp2);
std::cout << "time (" << avg << "): " <<
(tp2.tv_sec-tp1.tv_sec)*1000000000+(tp2.tv_nsec-tp1.tv_nsec) <<
" ns" << std::endl;
}
这个问题出现的条件还不清楚,但是:
- 如果不涉及继承,没问题(总是编译时)
- 如果我只做一个比较,没问题
- 如果所有项都是错误的,问题只会在比较分离时出现
那么,关于 typeid 的工作原理,有什么我没有得到的(当与类型名称一起使用时,它是否总是应该在编译时进行评估?)或者这可能是评估或优化中的 gcc 错误?
关于上下文,我将问题追溯到这个非常简化的示例,但我的目标是将 typeid 与模板类型一起使用(因为无法实现部分函数模板特化)。
感谢您的帮助!
【问题讨论】:
-
您的结论是完全基于您的代码执行需要多长时间,还是您对编译器实际输出的内容有更明确的证据?
-
你能设计你的程序而不需要
typeid吗?比较对象类型的程序被认为是格式不正确的 OO 程序。 -
Dennis> 是的,但我刚刚检查了 asm 代码,我可以确认在一种情况下,有 6 条指令在两个 clock_gettime 调用之间没有跳转,而在另一种情况下,有 15 条指令有 2 次跳转包括一个明显的循环。
-
您已经验证编译器没有执行您认为明显的优化。但这并没有说明编译器是否在编译时执行
typeid表达式。 -
Thomas> 我知道我应该做模板特化而不是类型比较。但在我的情况下,这会导致大量代码重复和/或增加复杂性。如果某些类还没有实现,我只想禁用代码的某些部分,类型比较确实是更具可读性和简单的解决方案,只要在编译时完成,我认为它不会那么讨厌...
标签: c++ gcc g++ compile-time typeid