The typeid
operator returns a const reference to a type_info
object that describes type-id or the type of expression. If expression is an lvalue (not a pointer) of a polymorphic class, the type_info of the most-derived class is returned. Otherwise, expression is not evaluated, and the type_info of its static type is returned.
Each distinct type has its own associated type_info object, but type synonyms (such as those created with typedef) have the same type_info object. 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. There is no guarantee that the same std::type_info instance will be referred to by all evaluations of the typeid expression on the same type, although std::type_info::hash_code of those type_info objects would be identical, as would be their std::type_index.
const std::type_info& ti1 = typeid(A); const std::type_info& ti2 = typeid(A); assert(&ti1 == &ti2); // Not guaranteed assert(ti1.hash_code() == ti2.hash_code()); // Guaranteed assert(std::type_index(ti1) == std::type_index(ti2)); // Guaranteed
Example
// Non-polymorphic struct Base {}; struct Derived : Base {}; // Polymorphic struct Base2 { virtual void foo() {} }; struct Derived2 : Base2 {}; int main() { int myint = 50; std::string mystr = "string"; double *mydoubleptr = nullptr; // output : int std::cout << typeid(myint).name(); // Non-polymorphic lvalue is a static type Derived d1; Base& b1 = d1; // Output : Base std::cout << typeid(b1).name(); // Polymorphic lvalue is a static type Derived2 d2; Base2& b2 = d2; // Output : Derived2 std::cout << typeid(b2).name(); }