Utiliser l'opérateur typeid en C++

Jinku Hu 12 octobre 2023
Utiliser l'opérateur typeid en C++

Cet article explique et montre comment utiliser l’opérateur typeid en C++.

Utilisez l’opérateur typeid pour récupérer le nom de type de l’objet en C++

Vous pouvez utiliser l’opérateur typeid pour récupérer les informations de type de l’expression ou de l’objet donné. Il renvoie une référence au type de bibliothèque standard std::type_info, qui est défini dans un en-tête <typeinfo>.

L’objet std::type_info a la fonction membre name que vous pouvez utiliser pour renvoyer une chaîne de caractères décrivant le type sous-jacent de l’objet argument. Notez que les informations de type récupérées par typeid dépendent de l’implémentation. À savoir, les compilateurs les plus courants gcc et clang renvoient des noms mutilés, comme le montre l’exemple de code suivant.

D’autres implémentations telles que Microsoft Visual C++ affichent des informations sous des formes plus lisibles. Cependant, gardez à l’esprit que vous pouvez toujours apprendre à identifier les noms des types intégrés affichés par l’ancienne implémentation. Par exemple, l’objet int renvoie un caractère i, et un pointeur vers l’objet int renvoie une chaîne de caractères 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;
}

Production:

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

          i1 type : i

En revanche, si nous appelons la commande typeid sur les références aux objets, nous constaterons que les informations de type récupérées ne sont pas toujours précises et parfois trop cryptiques pour être lisibles. L’exemple suivant montre un tel cas où le deuxième appel à l’opérateur typeid renvoie les informations de type de manière incorrecte.

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

Production:

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

Ce comportement peut être corrigé à l’aide de la fonction de bibliothèque Boost TypeIndex, type_id_with_cvr, qui peut renvoyer les informations de type avec précision. Généralement, les objets avec les modificateurs const, volatile,& et && provoquent tous des informations de type incorrectes lorsque l’opérateur typeid est utilisé ; par conséquent, vous devriez mieux vous fier à la fonction type_id_with_cvr.

L’exemple de code suivant nécessite l’installation de la bibliothèque Boost sur le système et la fonction type_id_with_cvr se trouve sous l’espace de noms 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;
}

Production:

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

Article connexe - C++ Operator