web-dev-qa-db-fra.com

'typeid' versus 'typeof' en C ++

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
138
Tim

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).

173
AnT

La principale différence entre les deux est la suivante

  • typeof est une construction de compilation et renvoie le type tel que défini lors de la compilation
  • typeid est une construction d'exécution et donne donc des informations sur le type d'exécution de la valeur.

typeof Référence: http://www.delorie.com/gnu/docs/gcc/gcc_36.html

typeid Référence: https://en.wikipedia.org/wiki/Typeid

43
JaredPar

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 .

26
Brian Campbell

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.
}
20
AraK

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
4

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);
3
Patrick K