4

タイプ名 (つまり、typeid(int)、typeid(std::string)...) を使用すると、コンパイル時に typeid が評価されることを確認したかったのです。

そのために、2 つの typeid 呼び出しの比較をループで繰り返し、最適化を有効にしてコンパイルしました。そうではありません)。

そして、コンパイラがコードを単純化する場合とそうでない場合があるため、奇妙な結果が得られます。私は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;
}

この問題が発生する条件は明確ではありませんが、
- 継承が含まれていない場合は問題ありません (常にコンパイル時)
- 比較を 1 回だけ行う場合は問題ありません
- 問題は比較の論理和でのみ発生します。すべての条件は誤りです

typeid がどのように機能するかについて私が得られなかったものがありますか (型名で使用される場合、コンパイル時に常に評価されることになっていますか?)、またはこれは評価または最適化における gcc のバグでしょうか?

コンテキストについては、この非常に単純化された例に問題を突き止めましたが、私の目標はテンプレート型で typeid を使用することです (部分的な関数テンプレートの特殊化は不可能であるため)。

ご協力いただきありがとうございます!

4

3 に答える 3

7

あなたの質問に対する答えはよくわかりませんが、 typeid の代わりに is_same<> メタ関数を使用すると、より望ましい結果が得られる可能性があります。このメタ関数にアクセスできない場合でも、非常に簡単に作成できます。


template < typename T1, typename T2 >
struct is_same
{
  enum { value = false }; // is_same represents a bool.
  typedef is_same<T1,T2> type; // to qualify as a metafunction.
};

template < typename T >
struct is_same
{
  enum { value = true };
  typedef is_same<T,T> type;
};
于 2010-05-20T20:19:56.493 に答える
2

For any type T, if T is polymorphic, the compiler is required to evaluate the typeid stuff at runtime. If T is non-polymorphic, the compiler is required to evaluate the typeid stuff at compile time. However, i cannot find the relevant reference in the C++ draft (n3000.pdf) for it.

Infact, in one of the projects that i worked on, this trick was used to find whether a class was polymorphic at runtime.

template <class T>  
bool isPolymorphic() {  
    bool answer=false; 
    T *t = new T(); 
    typeid(answer=true,*t);  
    delete t; 
    return answer;  
} 

I had asked a related question here on SO a few months back.

于 2010-05-20T21:23:37.910 に答える
2

typeidはランタイム型識別メカニズムの一部であり、その有用性を示唆しています。主な使用法は、実行時に基本クラスへのポインター/参照の動的型を識別することです。コンパイル時に型が静的に認識されている場合は、それらが何であるかを既に知っているため、それらを「識別する」必要はありません。

この例では、実行時に特定するものは何もありませんが、結果はコンパイル時にまったく役に立ちませtypeidん (テンプレートのメタプログラミングに必要な const 式には表示されません)。

だから私もお勧めしますis_same

于 2010-05-20T21:04:58.930 に答える