# RTTI: Run-Time Type Information

# Name of a type

You can retrieve the implementation defined name of a type in runtime by using the .name() member function of the std::type_info object returned by typeid.

#include <iostream>
#include <typeinfo>

int main()
    int speed = 110;

    std::cout << typeid(speed).name() << '\n';

Output (implementation-defined):


# dynamic_cast

Use dynamic_cast<>() as a function, which helps you to cast down through an inheritance hierarchy (main description (opens new window)).

If you must do some non-polymorphic work on some derived classes B and C, but received the base class A, then write like this:

class A { public: virtual ~A(){} };

class B: public A
{ public: void work4B(){} };

class C: public A
{ public: void work4C(){} };

void non_polymorphic_work(A* ap)
  if (B* bp =dynamic_cast<B*>(ap))
  if (C* cp =dynamic_cast<C*>(ap))

# The typeid keyword

The typeid keyword (opens new window) is a unary operator that yields run-time type information about its operand if the operand's type is a polymorphic class type. It returns an lvalue of type const std::type_info. Top-level cv-qualification are ignored.

struct Base {
    virtual ~Base() = default;
struct Derived : Base {};
Base* b = new Derived;
assert(typeid(*b) == typeid(Derived{})); // OK

typeid can also be applied to a type directly. In this case, first top-level references are stripped, then top-level cv-qualification is ignored. Thus, the above example could have been written with typeid(Derived) instead of typeid(Derived{}):

assert(typeid(*b) == typeid(Derived{})); // OK

If typeid is applied to any expression that is not of polymorphic class type, the operand is not evaluated, and the type info returned is for the static type.

struct Base {
    // note: no virtual destructor
struct Derived : Base {};
Derived d;
Base& b = d;
assert(typeid(b) == typeid(Base)); // not Derived
assert(typeid(std::declval<Base>()) == typeid(Base)); // OK because unevaluated

# When to use which cast in c++

Use dynamic_cast for converting pointers/references within an inheritance hierarchy.

Use static_cast for ordinary type conversions.

Use reinterpret_cast for low-level reinterpreting of bit patterns. Use with extreme caution.

Use const_cast for casting away const/volatile. Avoid this unless you are stuck using a const-incorrect API.