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&
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