Оператор typeid

Синтаксис

typeid(type-id)
typeid(expression)

Замечания

Оператор typeid позволяет определить тип объекта во время выполнения.

Результатом typeid является const type_info&. Значение является ссылкой на type_info объект, представляющий идентификатор типа или тип выражения, в зависимости от того, какая форма typeid используется. Дополнительные сведения см. в разделе type_info класса.

Оператор typeid не работает с управляемыми типами (абстрактными деклараторами или экземплярами). Сведения о получении Type указанного типа см. в разделе typeid.

Оператор typeid выполняет проверка во время выполнения при применении к l-значению типа полиморфного класса, где истинный тип объекта не может быть определен статическими сведениями. К таким случаям относятся следующие.

  • Ссылка на класс

  • Указатель, разыменовывая с помощью *

  • Подстрочный указатель ([ ]). (Небезопасно использовать подстрок с указателем на полиморфный тип.)

Если выражение указывает на тип базового класса, но объект фактически является типом, производным от этого базового класса, 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 ссылка, представляющая статический тип выражения. Статический тип выражения относится к типу выражения, известному во время компиляции. Семантика исполнения игнорируется при оценке статического типа выражения. Кроме того, ссылки по возможности игнорируются при определении статического типа выражения:

// 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 );
}

См. также

Сведения о типах среды выполнения
Ключевые слова