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 .
Aussi, voici le test de code de test que j'ai créé où j'ai découvert et qui 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)
}
production:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
name()
est définie par l' implémentation. Il n'est pas nécessaire qu'il s'agisse d'un nom d'identifiant C ++ valide, mais simplement de quelque chose qui identifie de manière unique le type. Il semble que votre implémentation utilise le schéma général de modification des noms du compilateur.Réponses:
Le langage C ++ n'a rien de tel que
typeof
. Vous devez rechercher une extension spécifique au compilateur. Si vous parlez de GCCtypeof
, une fonctionnalité similaire est présente dans C ++ 11 via le mot-clédecltype
. Encore une fois, C ++ n'a pas de teltypeof
mot clé.typeid
est un opérateur de langage C ++ qui renvoie des informations d'identification de type au moment de l'exécution. Il renvoie essentiellement untype_info
objet, qui est comparable à l'égalité avec d'autrestype_info
objets.Notez que la seule propriété définie de l'
type_info
objet renvoyé est d'être comparable à l'égalité et à la non-égalité, c'est-à-dire que lestype_info
objets décrivant différents types doivent être comparés non égaux, tandis que lestype_info
objets décrivant le même type doivent comparer égaux. Tout le reste est défini par l'implémentation. Les méthodes qui renvoient divers "noms" ne sont pas garanties de renvoyer quoi que ce soit de lisible par l'homme, et même pas garanties de renvoyer quoi que ce soit.Notez également que ce qui précède implique probablement (bien que la norme ne semble pas le mentionner explicitement) que des applications consécutives
typeid
du même type peuvent renvoyer destype_info
objets différents (qui, bien sûr, doivent encore comparer égaux).la source
decltype
? Je ne sais pas quelle est la politique générale, mais comme la question est étiquetée,C++
je m'attendrais à ce qu'elle fasse référence à la dernière norme. Repenser la question commeC++03
serait également une option à mon humble avis. Personnellement, je suis parfois assez confus, car je dois utiliser preC ++ 11 au travail et parfois je ne suis pas sûr de ce qui est vrai "pre11" ou "post11".decltype
n'est pas un remplacement pourtypeof
.typeof
fonctionne aussi sur les types tandisdecltype
que non. Par exemple,typeof(int)
isint
whiledecltype(int)
est une erreur.type_info
objets décrivant différents types doivent être comparés non égaux" . En fait, ce n'est pas garanti . L'opérateur d'inégalité a été supprimé dans C ++ 20 pour (je suppose) décourager de s'appuyer sur différents types de comparaison non-égaux. Mais si vous y réfléchissez, l'égalité n'est pas sûre si l'inégalité n'est pas sûre.La principale différence entre les deux est la suivante
typeof Référence: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
Référence typeid: https://en.wikipedia.org/wiki/Typeid
la source
typeid
peut fonctionner à l'exécution et retourner un objet décrivant le type d'exécution de l'objet, qui doit être un pointeur vers un objet d'une classe avec des méthodes virtuelles pour que RTTI (informations de type à l'exécution) soit stocké dans la classe. Il peut également donner le type à la compilation d'une expression ou d'un nom de type, s'il n'est pas donné un pointeur vers une classe avec des informations de type à l'exécution.typeof
est une extension GNU, et vous donne le type de n'importe quelle expression au moment de la compilation. Cela peut être utile, par exemple, pour déclarer des variables temporaires dans des macros qui peuvent être utilisées sur plusieurs types. En C ++, vous utiliseriez généralement des modèles à la place.la source
typeid
acceptera n'importe quelle expression, pas seulement celles qui évaluent à des objets avec des méthodes virtuelles. De plus,typeid
acceptera un nom de type , pas seulement une expression. Vous pouvez diretypeid(5)
outypeid(std::string)
si vous voulez.typeid
peut renvoyer des informations de type à l'exécution si disponibles, mais fournira des informations de type à la compilation pour tout le reste.Répondre à la question supplémentaire:
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 C ++ standard ne force pas les compilateurs à émettre le nom exact de la classe, c'est juste à 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 y a quelque chosedecltype
qui s'appelle qui fait le même travail AFAIK.Alors qu'il
typeid
est utilisé avec les types polymorphes. Par exemple, disons quecat
dériveanimal
:la source
typeid fournit le type des données au moment de l'exécution, lorsqu'il est demandé. Typedef est une construction au moment de la compilation qui définit un nouveau type comme indiqué par la suite. Il n'y a pas de typeof dans la sortie C ++ qui apparaît comme (affiché comme des commentaires inscrits):
la source
Vous pouvez utiliser Boost demangle pour créer un joli nom:
et quelque chose comme
la source