Namespaces
Variants
Views
Actions

typeid operator

From cppreference.com
< cpp‎ | language
Revision as of 03:41, 8 October 2013 by Cubbi (Talk | contribs)

 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 

Queries information of a type.

Used where the dynamic type of a polymorphic class must be known.

Contents

Syntax

typeid( type ) (1)
typeid( expression ) (2)

Header <typeinfo> must be included before using typeid operator.

The typeid expression is lvalue expression which refers to an object with static storage duration, of the polymorphic type const std::type_info or of some type derived from it.

Explanation

1) Refers to a std::type_info object representing the type type. If type is a reference type, the result refers to the referenced type.
2) Examines the expression expression
a) If expression is a glvalue expression that identifies an object of a polymorphic type (that is, a class that declares or inherits at least one virtual function), the typeid expression evaluates the expression and then refers to the std::type_info object that represents the dynamic type of the expression. If the result of the evaluated expression is a null pointer, an exception of type std::bad_typeid or a type derived from std::bad_typeid is thrown.
b) If expression is not a glvalue expression of polymorphic type, typeid does not evaluate the expression, and the std::type_info object it identifies represents the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.

In all cases, cv-qualifiers are ignored by typeid (that is, typeid(T)==typeid(const T))

typeid cannot be applied to an incomplete type.

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

Keywords

typeid

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.

Example

the example showing output using one of the implementations where typeinfo::name prints full type names; filter through c++filt -t if using gcc or similar

#include <iostream>
#include <string>
#include <typeinfo>
 
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);
    std::cout << "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-polymoprhic expression
        std::cout << "mydoubleptr points to " << typeid(*mydoubleptr).name() << '\n'; 
        // dereferencing a null pointer: not okay for a polymorphic lvalue
        Derived2* bad_ptr = NULL;
        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';
    }
}

Possible output:

myint has type: int
mystr has type: std::basic_string<char, std::char_traits<char>, std::allocator<char> >
mydoubleptr has type: double*
50std::cout<<myint has type : std::basic_ostream<char, std::char_traits<char> >
printf("%d\n",myint) has type : int
reference to non-polymorphic base: Base
reference to polymorphic base: Derived2
mydoubleptr points to double
bad_ptr points to...  caught std::bad_typeid