cpp/language/typeid

Queries information of a type.

Used where the of a  must be known and for static type identification.

Syntax
The header must be included   before using, otherwise the program is ill-formed.

The typeid expression is an which refers to an object with, of const-qualified version of the polymorphic type std or some type derived from it.

Explanation
If the type of or  is a class type or a reference to a class type, then that class type cannot be an.

@1@ Refers to a std object representing the type. If is a reference type, the result refers to a std object representing the cv-unqualified version of the referenced type. @2@ Examines the expression
 * @a@ If is  expression that identifies an  (that is, a class that declares or inherits at least one ), the  expression evaluates the expression and then refers to the std object that represents the dynamic type of the expression. If  is obtained by applying the unary  operator to a pointer and the pointer is a null pointer value, an exception of  is thrown.
 * @b@ If is not  expression of polymorphic type,  does, and the std object it identifies represents the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.

If the type of or  is cv-qualified, the result of the  refers to a std object representing the cv-unqualified type (that is, ).

If is used on an object under construction or destruction (in a destructor or in a constructor, including constructor's  or ), then the std object referred to by this  represents the class that is being constructed or destroyed even if it is not the most-derived class.

Example
{{example|The example showing output using one of the implementations where {{lc|type_info::name}} returns full type names; filter through c++filt -t if using gcc or similar.
 * p=true
 * code=
 * 1) include
 * 2) include
 * 3) include

struct Base {}; // non-polymorphic struct Derived : Base {};

struct Base2 { virtual void foo {} }; // polymorphic struct Derived2 : Base2 {};

int main {   int myint = 50; std::string mystr = "string"; double *mydoubleptr = nullptr; std::cout << "myint has type: " << typeid(myint).name << '\n' << "mystr has type: " << typeid(mystr).name << '\n' << "mydoubleptr has type: " << typeid(mydoubleptr).name << '\n'; // std::cout << myint is a glvalue expression of polymorphic type; it is evaluated const std::type_info& r1 = typeid(std::cout << myint); // side-effect: prints 50 std::cout << '\n' << "std::cout<<myint has type : " << r1.name << '\n'; // std::printf is not a glvalue expression of polymorphic type; NOT evaluated const std::type_info& r2 = typeid(std::printf("%d\n", myint)); std::cout << "printf(\"%d\\n\",myint) has type : " << r2.name << '\n'; // Non-polymorphic lvalue is a static type Derived d1; Base& b1 = d1; std::cout << "reference to non-polymorphic base: " << typeid(b1).name << '\n'; Derived2 d2; Base2& b2 = d2; std::cout << "reference to polymorphic base: " << typeid(b2).name << '\n'; try {       // dereferencing a null pointer: okay for a non-polymorphic expression std::cout << "mydoubleptr points to " << typeid(*mydoubleptr).name << '\n'; // dereferencing a null pointer: not okay for a polymorphic lvalue Derived2* bad_ptr = nullptr; std::cout << "bad_ptr points to... "; std::cout << typeid(*bad_ptr).name << '\n'; }   catch (const std::bad_typeid& e)    { std::cout << " caught " << e.what << '\n'; } }
 * output=

== output from Clang
== myint has type: i mystr has type: NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE mydoubleptr has type: Pd 50 std::cout< mydoubleptr has type: double * __ptr64 50 std::cout< printf("%d\n",myint) has type : int reference to non-polymorphic base: struct Base reference to polymorphic base: struct Derived2 mydoubleptr points to double bad_ptr points to... caught Attempted a typeid of nullptr pointer! }}