Use o operador typeid em C++

Jinku Hu 12 outubro 2023
Use o operador typeid em C++

Este artigo explica e demonstra como utilizar o operador typeid em C++.

Use o operador typeid para recuperar o nome do tipo do objeto em C++

Você pode usar o operador typeid para recuperar as informações de tipo de uma determinada expressão ou objeto. Ele retorna uma referência ao tipo de biblioteca padrão std::type_info, que é definido em um cabeçalho <typeinfo>.

O objeto std::type_info tem a função de membro name que você pode utilizar para retornar uma cadeia de caracteres que descreve o tipo subjacente do objeto de argumento. Observe que as informações de tipo recuperadas por typeid dependem da implementação. Ou seja, os compiladores mais comuns gcc e clang retornam nomes mutilados, conforme demonstrado no próximo exemplo de código.

Outras implementações, como o Microsoft Visual C++, exibem informações em formas mais legíveis. Ainda assim, lembre-se de que você ainda pode aprender a identificar os nomes dos tipos integrados exibidos pela implementação anterior. Por exemplo, o objeto int retorna um caractere i e um ponteiro para o objeto int retorna uma cadeia 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;
}

Resultado:

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

          i1 type : i

Por outro lado, se chamarmos o comando typeid em referências a objetos, descobriremos que as informações de tipo recuperadas nem sempre são precisas e às vezes muito enigmáticas para serem legíveis. O exemplo a seguir mostra um caso em que a segunda chamada para o operador typeid retorna as informações de tipo incorretamente.

#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;
}

Resultado:

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

Esse comportamento pode ser corrigido usando a função de biblioteca Boost TypeIndex, type_id_with_cvr, que pode retornar as informações de tipo com precisão. Geralmente, os objetos com os modificadores const, volatile, & e && causam a informação de tipo incorreta quando o operador typeid é usado; portanto, você deve confiar melhor na função type_id_with_cvr.

O exemplo de código a seguir requer que a biblioteca Boost seja instalada no sistema e a função type_id_with_cvr está sob o namespace 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;
}

Resultado:

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

Artigo relacionado - C++ Operator