Usa l'operatore typeid in C++

Jinku Hu 12 ottobre 2023
Usa l'operatore typeid in C++

Questo articolo spiega e dimostra come utilizzare l’operatore typeid in C++.

Utilizzare l’operatore typeid per recuperare il nome del tipo dell’oggetto in C++

È possibile utilizzare l’operatore typeid per recuperare le informazioni sul tipo dell’espressione o dell’oggetto dati. Restituisce un riferimento al tipo di libreria standard std::type_info, che è definito in un’intestazione <typeinfo>.

L’oggetto std::type_info ha la funzione membro name che puoi utilizzare per restituire una stringa di caratteri che descrive il tipo sottostante dell’oggetto argomento. Nota che le informazioni sul tipo recuperate da typeid dipendono dall’implementazione. Vale a dire, i compilatori più comuni gcc e clang restituiscono nomi alterati, come dimostrato nel prossimo esempio di codice.

Altre implementazioni come Microsoft Visual C++ visualizzano le informazioni in forme più leggibili. Tuttavia, tieni presente che puoi ancora imparare a identificare i nomi per i tipi incorporati visualizzati dalla precedente implementazione. Ad esempio, l’oggetto int restituisce un carattere i e un puntatore all’oggetto int restituisce una stringa di caratteri 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;
}

Produzione:

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

          i1 type : i

D’altra parte, se chiamiamo il comando typeid sui riferimenti agli oggetti, scopriremo che le informazioni sul tipo recuperate non sono sempre accurate e talvolta troppo criptiche per essere leggibili. L’esempio seguente mostra un caso del genere in cui la seconda chiamata all’operatore typeid restituisce le informazioni sul tipo in modo errato.

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

Produzione:

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

Questo comportamento può essere corretto utilizzando la funzione di libreria Boost TypeIndex, type_id_with_cvr, che può restituire le informazioni sul tipo in modo accurato. In genere, gli oggetti con i modificatori const, volatile, & e && causano tutti le informazioni di tipo errate quando viene utilizzato l’operatore typeid; quindi, dovresti fare affidamento sulla funzione type_id_with_cvr.

Il seguente esempio di codice richiede l’installazione della libreria Boost sul sistema e la funzione type_id_with_cvr si trova nello spazio dei nomi 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;
}

Produzione:

Base & Base2&
Autore: 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

Articolo correlato - C++ Operator