From cppreference.com
Queries information of a type.
Used where the
of a
must be known and for static type identification.
Syntax
typeid (type)(1) typeid (expression)(2) The typeid expression is an
which refers to an object with
, of const-qualified version of the polymorphic type
or some type derived from it.
If the standard library definition of
is not visible when using typeid, the program is ill-formed.
Explanation
If type or the type of expression is a class type or a reference to a class type, then that class type cannot be an
.
1) Refers to a
object representing type. If type is a reference type, the result refers to a
object representing the cv-unqualified version of the referenced type.
2) Examines expression :
If expression is an
(until C++11)a
(since C++11) expression that identifies an
(that is, a class that declares or inherits at least one
), the typeid expression evaluates the expression and then refers to the
object that represents the dynamic type of the expression.
If expression is an
and its operand evaluates to a
, an exception of a type matching handlers of type
is thrown
.
Otherwise, typeid does
, and the
object it identifies represents the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.
, however, is (formally) performed for prvalue arguments: the argument must be destructible in the context in which the typeid expression appears.
(since C++17)If type or the type of expression is cv-qualified, the result of the typeid refers to a
object representing the cv-unqualified type (that is, typeid(constT)==typeid(T)).
If typeid is used on an object under construction or destruction (in a destructor or in a constructor, including constructor's
or
), then the
object referred to by this typeid represents the class that is being constructed or destroyed even if it is not the most-derived class.
In other contexts, evaluating such an expression results in undefined behavior.
Notes
When applied to an expression of polymorphic type, evaluation of a typeid expression may involve runtime overhead (a virtual table lookup), otherwise typeid expression is resolved at compile time.
It is unspecified whether the destructor for the object referred to by typeid is executed at the end of the program.
There is no guarantee that the same
object will be referred to by all evaluations of the typeid expression on the same type, although they would compare equal,
of those type_info objects would be identical, as would be their
.
conststd::type_info&ti1=typeid(A);conststd::type_info&ti2=typeid(A);assert(&ti1==&ti2);// not guaranteedassert(ti1==ti2);// guaranteedassert(ti1.hash_code()==ti2.hash_code());// guaranteedassert(std::type_index(ti1)==std::type_index(ti2));// guaranteedFeature-test macro ValueStdFeature
(C++20)polymorphic typeid in constant expressions Keywords
Example
The example showing output using one of the implementations where type_info::name returns full type names; filter through c++filt -t if using gcc or similar.
Run this code
#include<iostream>#include<string>#include<typeinfo>structBase{};// non-polymorphicstructDerived:Base{};structBase2{virtualvoidfoo(){}};// polymorphicstructDerived2:Base2{};intmain(){intmyint=50;std::stringmystr="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 evaluatedconststd::type_info&r1=typeid(std::cout<<myint);// side-effect: prints 50std::cout<<'\n'<<"std::cout<<myint has type : "<<r1.name()<<'\n';// std::printf() is not a glvalue expression of polymorphic type; NOT evaluatedconststd::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 typeDerivedd1;Base&b1=d1;std::cout<<"reference to non-polymorphic base: "<<typeid(b1).name()<<'\n';Derived2d2;Base2&b2=d2;std::cout<<"reference to polymorphic base: "<<typeid(b2).name()<<'\n';try{// dereferencing a null pointer: okay for a non-polymorphic expressionstd::cout<<"mydoubleptr points to "<<typeid(*mydoubleptr).name()<<'\n';// dereferencing a null pointer: not okay for a polymorphic lvalueDerived2*bad_ptr=nullptr;std::cout<<"bad_ptr points to... ";std::cout<<typeid(*bad_ptr).name()<<'\n';}catch(conststd::bad_typeid&e){std::cout<<" caught "<<e.what()<<'\n';}}Possible output:
======== output from Clang ======== myint has type: i mystr has type: NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE mydoubleptr has type: Pd 50 std::cout<<myint has type : NSt3__113basic_ostreamIcNS_11char_traitsIcEEEE printf("%d\n",myint) has type : i reference to non-polymorphic base: 4Base reference to polymorphic base: 8Derived2 mydoubleptr points to d bad_ptr points to... caught std::bad_typeid ======== output from MSVC ======== myint has type: int mystr has type: class std::basic_string<char,struct std::char_traits<char>,⮠ class std::allocator<char> > mydoubleptr has type: double * __ptr64 50 std::cout<<myint has type : class std::basic_ostream<char,struct std::char_traits<char> > 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! Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
C++98 when typeid is applied to a reference to cv-qualified
type, the result represented the referenced type the result represents the
cv-unqualified referenced type
C++98 the wording regarding top-level
cv-qualification might be misinterpreted improved the wording
C++98 typeid was only allowed to throw
allowed to throw
matchable derived classes
C++98 it was unclear whether null pointer dereference
can be checked in subexpressions of expressiononly checked at top level See also
contains some type’s information, the class returned by the typeid operator
(class)
(C++11)
wrapper around a
object, that can be used as index in associative and unordered associative containers
(class)