typeid
演算子
構文
typeid(type-id)
typeid(expression)
解説
typeid
演算子は、オブジェクトの型を実行時に決定できるようにします。
typeid
の結果は const type_info&
です。 値は、使用されている typeid
の形式に応じて、type-id または 式 の形式を表す type_info
オブジェクトへの参照です。 詳細については、「type_info クラス」をご覧ください。
typeid
演算子は、マネージド型 (抽象宣言子またはインスタンス) では機能しません。 指定された型の Type を取得する方法の詳細については、「typeid」をご覧ください。
typeid
演算子は、オブジェクトの実際の型を指定された静的な情報によって判断できない場合に、ポリモーフィックなクラス型の左辺値への適用時にランタイム チェックを実行します。 そのようなケースを次に示します。
クラスへの参照
*
で逆参照されるポインター添字付きのポインター (
[ ]
)。 (一般に、ポリモーフィックな型へのポインターで添字を使用すると、安全ではありません)。
式が基底クラス型を指し示していても、実際にはオブジェクトがその基底クラスから派生した型である場合、派生クラスの type_info
参照が結果になります。 式はポリモーフィック型 (仮想関数のあるクラス) をポイントする必要があります。 それ以外の場合、結果は式で参照される静的クラスの type_info
です。 さらに、ポインターが指し示すオブジェクトが使用されるように、ポインターを逆参照する必要があります。 ポインターの逆参照が行われない場合、結果はポインターが指しているものではなく、ポインターの type_info
です。 次に例を示します。
// expre_typeid_Operator.cpp
// compile with: /GR /EHsc
#include <iostream>
#include <typeinfo>
class Base {
public:
virtual void vvfunc() {}
};
class Derived : public Base {};
using namespace std;
int main() {
Derived* pd = new Derived;
Base* pb = pd;
cout << typeid( pb ).name() << endl; //prints "class Base *"
cout << typeid( *pb ).name() << endl; //prints "class Derived"
cout << typeid( pd ).name() << endl; //prints "class Derived *"
cout << typeid( *pd ).name() << endl; //prints "class Derived"
delete pd;
}
式がポインターを逆参照し、そのポインターの値がゼロの場合、typeid
は bad_typeid 例外をスローします。 ポインターが有効なオブジェクトを指していない場合は、__non_rtti_object
例外がスローされます。 オブジェクトが無効であるためにエラーをトリガーした RTTI の分析が試行されたことを示します。 (たとえば、無効なポインターであるか、またはコードが /GR でコンパイルされていません)。
式がオブジェクトの基底クラスへのポインターまたは参照でない場合、結果は式の静的な型を表す type_info
参照になります。 式の static type は、コンパイル時に既知のときに式の型を参照します。 実行セマンティクスは、式の静的な型を評価するときは無視されます。 さらに、式の静的な型を判断するときに、参照は可能な限り無視されます。
// expre_typeid_Operator_2.cpp
#include <typeinfo>
int main()
{
typeid(int) == typeid(int&); // evaluates to true
}
typeid
は、テンプレート パラメーターの型を決定するためにテンプレート内で使用することもできます。
// expre_typeid_Operator_3.cpp
// compile with: /c
#include <typeinfo>
template < typename T >
T max( T arg1, T arg2 ) {
cout << typeid( T ).name() << "s compared." << endl;
return ( arg1 > arg2 ? arg1 : arg2 );
}