Namespaces
Variants

typeid operator

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Consulta información de un tipo.

Se utiliza cuando el dynamic type de un polymorphic object debe ser conocido y para identificación de tipo estático.

Contenidos

Sintaxis

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

La expresión typeid es una expresión lvalue que se refiere a un objeto con almacenamiento estático , del tipo polimórfico calificado como const std::type_info o algún tipo derivado del mismo.

Si la definición de la biblioteca estándar de std::type_info no es visible al usar typeid , el programa está mal formado.

Explicación

Si type o el tipo de expression es un tipo clase o una referencia a un tipo clase, entonces ese tipo clase no puede ser un incomplete type .

1) Se refiere a un objeto std::type_info que representa el type . Si type es un tipo referencia, el resultado se refiere a un objeto std::type_info que representa la versión sin calificadores cv del tipo referenciado.
2) Examina la expresión :
  • De lo contrario, typeid no evalúa la expresión , y el objeto std::type_info que identifica representa el tipo estático de la expresión. No se realizan conversiones de lvalue-a-rvalue, array-a-puntero o función-a-puntero.
  • La materialización temporal , sin embargo, se realiza (formalmente) para argumentos prvalue: el argumento debe ser destructible en el contexto donde aparece la expresión typeid .
(since C++17)

Si type o el tipo de expression está calificado con cv, el resultado de typeid se refiere a un objeto std::type_info que representa el tipo sin calificación cv (es decir, typeid ( const T ) == typeid ( T ) ).

Si typeid se utiliza en un objeto en construcción o destrucción (en un destructor o en un constructor, incluyendo la lista de inicializadores del constructor o los inicializadores predeterminados de miembros ), entonces el objeto std::type_info al que se refiere este typeid representa la clase que se está construyendo o destruyendo, incluso si no es la clase más derivada.

  1. En otros contextos, evaluar dicha expresión resulta en comportamiento indefinido.

Notas

Cuando se aplica a una expresión de tipo polimórfico, la evaluación de una expresión typeid puede implicar sobrecarga en tiempo de ejecución (una búsqueda en la tabla virtual), de lo contrario la expresión typeid se resuelve en tiempo de compilación.

No está especificado si el destructor para el objeto referido por typeid se ejecuta al final del programa.

No hay garantía de que el mismo std::type_info objeto sea referido por todas las evaluaciones de la expresión typeid en el mismo tipo, aunque compararían iguales, el std::type_info::hash_code de esos objetos type_info sería idéntico, al igual que su std::type_index .

const std::type_info& ti1 = typeid(A);
const std::type_info& ti2 = typeid(A);
assert(&ti1 == &ti2); // no garantizado
assert(ti1 == ti2); // garantizado
assert(ti1.hash_code() == ti2.hash_code()); // garantizado
assert(std::type_index(ti1) == std::type_index(ti2)); // garantizado

Palabras clave

typeid

Ejemplo

El ejemplo muestra la salida usando una de las implementaciones donde type_info::name devuelve nombres de tipo completos; filtrar a través de c++filt -t si se usa gcc o 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); // 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';
    {
{

Salida posible:

======== 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!

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 492 C++98 cuando typeid se aplica a una referencia a tipo cv-calificado,
el resultado representaba el tipo referenciado
el resultado representa el
tipo referenciado sin calificación cv
CWG 1416 C++98 la redacción sobre calificación cv de nivel superior
podría ser malinterpretada
se mejoró la redacción
CWG 1431 C++98 typeid solo podía lanzar std::bad_typeid se permite lanzar
clases derivadas comparables
CWG 1954 C++98 no estaba claro si la desreferencia de puntero nulo
puede verificarse en subexpresiones de expresión
solo se verifica a nivel superior

Véase también

contiene información de algún tipo, la clase devuelta por el operador typeid
(clase)