Je me demande quelle est la différence entre typeid
et typeof
en C++. Voici ce que je sais:
typeid
est mentionné dans la documentation de type_info qui est définie dans le fichier d'en-tête C++ typeinfo .
typeof
est défini dans l'extension GCC pour C et dans la bibliothèque C++ Boost .
En outre, voici le test de code de test que j'ai créé et où j'ai découvert que typeid
ne renvoie pas ce que j'attendais. Pourquoi?
main.cpp
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person {
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person {
// ... Employee members ...
};
int main () {
Person person;
Employee employee;
Person *ptr = &employee;
int t = 3;
std::cout << typeid(t).name() << std::endl;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer
// to a polymorphic class)
}
sortie:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
Le langage C++ n'a pas de telle chose que typeof
. Vous devez regarder une extension spécifique au compilateur. Si vous parlez de typeof
de GCC, une fonctionnalité similaire est présente dans C++ 11 via le mot clé decltype
. Encore une fois, C++ n'a pas ce mot clé typeof
.
typeid
est un opérateur de langage C++ qui renvoie des informations d'identification de type lors de l'exécution. Il retourne essentiellement un objet type_info
, qui est comparable à d'autres objets type_info
.
Notez que la seule propriété définie de l'objet retourné type_info
est qu'elle est comparable et non comparable, c'est-à-dire que les objets type_info
décrivant différents types doivent être comparés de manière non égale, tandis que type_info
les objets décrivant le même type doivent être comparés égaux. Tout le reste est défini par l'implémentation. Les méthodes qui renvoient divers "noms" ne sont pas garanties pour pouvoir renvoyer quoi que ce soit lisible par l'homme, et même pour ne rien renvoyer.
Notez également que ce qui précède implique probablement (bien que le standard ne semble pas le mentionner explicitement) que des applications consécutives de typeid
au même type pourraient renvoyer différents objets type_info
(qui, bien entendu, doivent être comparés égaux).
La principale différence entre les deux est la suivante
typeof Référence: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
typeid Référence: https://en.wikipedia.org/wiki/Typeid
typeid
peut fonctionner à l'exécution et renvoyer un objet décrivant le type d'exécution de l'objet, qui doit être un pointeur sur un objet d'une classe avec des méthodes virtuelles afin RTTI (run informations de type -time) à stocker dans la classe. Il peut également indiquer le type de compilation d'une expression ou un nom de type, à moins qu'un pointeur ne soit attribué à une classe contenant des informations de type à l'exécution.
typeof
est une extension GNU et vous donne le type de toute expression au moment de la compilation. Cela peut être utile, par exemple, pour déclarer des variables temporaires dans des macros pouvant être utilisées sur plusieurs types. En C++, vous utiliseriez généralement templates .
Répondre à la question supplémentaire:
mon code de test suivant pour typeid ne génère pas le nom de type correct. Qu'est-ce qui ne va pas?
Il n'y a rien de mal. Ce que vous voyez est la représentation sous forme de chaîne du nom du type. Le standard C++ n'oblige pas les compilateurs à émettre le nom exact de la classe, il incombe simplement à l'implémenteur (fournisseur du compilateur) de décider ce qui convient. En bref, les noms appartiennent au compilateur.
Ce sont deux outils différents. typeof
renvoie le type d'une expression, mais ce n'est pas standard. Dans C++ 0x, il existe quelque chose appelé decltype
qui effectue le même travail autant que je sache.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
Alors que typeid
est utilisé avec les types polymorphes. Par exemple, supposons que cat
dérive animal
:
animal* a = new cat; // animal has to have at least one virtual function
...
if( typeid(*a) == typeid(cat) )
{
// the object is of type cat! but the pointer is base pointer.
}
typeid fournit le type des données au moment de l'exécution, lorsque demandé. Typedef est une construction de compilation qui définit un nouveau type comme indiqué par la suite. Il n'y a pas de typeof dans C++ La sortie apparaît sous la forme (affichée sous forme de commentaires):
std::cout << typeid(t).name() << std::endl; // i
std::cout << typeid(person).name() << std::endl; // 6Person
std::cout << typeid(employee).name() << std::endl; // 8Employee
std::cout << typeid(ptr).name() << std::endl; // P6Person
std::cout << typeid(*ptr).name() << std::endl; //8Employee
Vous pouvez utiliser Boost demangle pour obtenir un joli nom:
#include <boost/units/detail/utility.hpp>
et quelque chose comme
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);