Utilice el operador typeid en C++

Jinku Hu 12 octubre 2023
Utilice el operador typeid en C++

Este artículo explica y demuestra cómo utilizar el operador typeid en C++.

Utilice el operador typeid para recuperar el nombre de tipo del objeto en C++

Puede utilizar el operador typeid para recuperar la información de tipo de la expresión u objeto dado. Devuelve una referencia al tipo de biblioteca estándar std::type_info, que se define en un encabezado <typeinfo>.

El objeto std::type_info tiene la función miembro name que puede utilizar para devolver una cadena de caracteres que describe el tipo subyacente del objeto de argumento. Tenga en cuenta que la información de tipo recuperada por typeid depende de la implementación. Es decir, los compiladores más comunes gcc y clang devuelven nombres destrozados, como se muestra en el siguiente ejemplo de código.

Otras implementaciones como Microsoft Visual C++ muestran información en formas más legibles. Aún así, tenga en cuenta que aún puede aprender a identificar los nombres de los tipos integrados que muestra la implementación anterior. Por ejemplo, el objeto int devuelve un carácter i y un puntero al objeto int devuelve una cadena de caracteres Pi.

#include <iostream>
#include <string>
#include <typeinfo>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main() {
  int i1 = 1234;
  string str1("arbitrary string");
  auto ptr = &i1;

  cout << "i1 type: " << typeid(i1).name() << '\n'
       << "str1 type: " << typeid(str1).name() << '\n'
       << "ptr type: " << typeid(ptr).name() << endl;

  const std::type_info& r1 = typeid(i1);
  cout << '\n' << "i1 type: " << r1.name() << '\n';

  return EXIT_SUCCESS;
}

Producción :

i1 type: i
str1 type: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
ptr type: Pi

i1 type: i

Por otro lado, si llamamos al comando typeid sobre referencias a objetos, encontraremos que la información de tipo recuperada no siempre es precisa y, a veces, demasiado críptica para ser legible. El siguiente ejemplo muestra un caso en el que la segunda llamada al operador typeid devuelve la información del tipo de forma incorrecta.

#include <iostream>
#include <string>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {};
struct Derived : Base {};

struct Base2 {
  virtual void foo() {}
};
struct Derived2 : Base2 {};

int main() {
  Derived d1;
  Base& b1 = d1;
  cout << "non-polymorphic base: " << typeid(b1).name() << '\n';

  Derived2 d2;
  Base2& b2 = d2;
  cout << "polymorphic base: " << typeid(b2).name() << '\n';

  return EXIT_SUCCESS;
}

Producción :

non-polymorphic base: 4Base
polymorphic base: 8Derived2

Este comportamiento se puede corregir utilizando la función de biblioteca Boost TypeIndex, type_id_with_cvr, que puede devolver la información del tipo con precisión. Generalmente, los objetos con los modificadores const, volatile, & y && causan todos la información de tipo incorrecta cuando se utiliza el operador typeid; por lo tanto, debería confiar mejor en la función type_id_with_cvr.

El siguiente ejemplo de código requiere que la biblioteca Boost esté instalada en el sistema, y ​​la función type_id_with_cvr está en el espacio de nombres boost::typeindex.

#include <boost/type_index.hpp>
#include <iostream>
#include <string>
#include <typeinfo>

using boost::typeindex::type_id_with_cvr;
using std::cout;
using std::endl;

struct Base {};
struct Derived : Base {};

struct Base2 {
  virtual void foo() {}
};
struct Derived2 : Base2 {};

int main() {
  Derived d1;
  Base& b1 = d1;

  Derived2 d2;
  Base2& b2 = d2;

  cout << type_id_with_cvr<decltype(b1)>().pretty_name() << '\n';
  cout << type_id_with_cvr<decltype(b2)>().pretty_name() << '\n';

  return EXIT_SUCCESS;
}

Producción :

Base&
Base2&
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C++ Operator