En C ++, comment trouver le type d'une variable?
En C ++, comment trouver le type d'une variable?
Réponses:
Vous pouvez utiliser l'opérateur typeid :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
signifie entier sur votre compilateur. Les noms renvoyés ne sont pas spécifiés par la norme.
typeid
sont très abrégés, spécifiques au compilateur et ne sont pas destinés à la consommation humaine. Vous pouvez les «démêler» (c'est le terme réel!), Soit dans le code avec quelque chose comme gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , avec des utilitaires de ligne de commande tels que c++filt
, ou avec l'un des différents démangleurs en ligne comme demangler.com .
Si vous avez une variable
int k;
Vous pouvez obtenir son type en utilisant
cout << typeid(k).name() << endl;
Voir le fil de discussion suivant sur SO: Question similaire
La principale différence entre C ++ et Javascript est que C ++ est un langage de type statique, alors que javascript est dynamique.
Dans les langages typés dynamiques, une variable peut contenir n'importe quoi, et son type est donné par la valeur qu'elle détient, instant par instant. Dans les langages à typage statique, le type d'une variable est déclaré et ne peut pas changer.
Il peut y avoir une répartition dynamique et une composition et un sous-typage d'objets (héritage et fonctions virtuelles) ainsi qu'une répartition statique et un sur-typage (via le modèle CRTP), mais dans tous les cas, le type de variable doit être connu du compilateur.
Si vous êtes en mesure de ne pas savoir ce que c'est ou ce que cela pourrait être, c'est parce que vous avez conçu quelque chose car le langage a un système de type dynamique.
Si tel est le cas, vous feriez mieux de repenser votre conception, car elle va dans un pays qui n'est pas naturel pour la langue que vous utilisez (la plupart comme aller sur une autoroute avec une chenille, ou dans l'eau avec une voiture)
En général, vouloir trouver le type d'une variable en C ++ est la mauvaise question. Cela a tendance à être quelque chose que vous emportez avec des langages procéduraux comme par exemple C ou Pascal.
Si vous souhaitez coder différents comportements en fonction du type, essayez d'en savoir plus sur la surcharge de fonctions et l' héritage d'objets . Cela n'aura pas de sens immédiat lors de votre premier jour de C ++, mais continuez.
Je crois avoir un cas d'utilisation valide pour utiliser typeid (), de la même manière qu'il est valide d'utiliser sizeof (). Pour une fonction de modèle, j'ai besoin de cas particulier du code basé sur la variable de modèle, afin d'offrir un maximum de fonctionnalités et de flexibilité.
Il est beaucoup plus compact et maintenable que l'utilisation du polymorphisme, de créer une instance de la fonction pour chaque type pris en charge. Même dans ce cas, je pourrais utiliser cette astuce pour écrire le corps de la fonction une seule fois:
Notez que parce que le code utilise des modèles, l'instruction switch ci-dessous doit se résoudre statiquement en un seul bloc de code, optimisant ainsi tous les faux cas, AFAIK.
Considérez cet exemple, où nous pouvons avoir besoin de gérer une conversion si T est un type par rapport à un autre. Je l'utilise pour la spécialisation de classe pour accéder au matériel où le matériel utilisera le type myClassA ou myClassB. En cas d'incohérence, je dois passer du temps à convertir les données.
switch ((typeid(T)) {
case typeid(myClassA):
// handle that case
break;
case typeid(myClassB):
// handle that case
break;
case typeid(uint32_t):
// handle that case
break;
default:
// handle that case
}
typeid
ne peut tout simplement pas être une vérification statique à la compilation - par définition - donc cela ne facilite aucune optimisation. For a template function, I need to special case the code based on the template variable
Bon, donc ce que vous voulez vraiment, c'est le polymorphisme statique via l'idiome CRTP. C'est exactement ce que cela permet.
Je ne sais pas si ma réponse pourrait aider.
La réponse courte est que vous n'avez pas vraiment besoin / ne voulez pas connaître le type de variable pour l'utiliser.
Si vous avez besoin de donner un type à une variable statique, vous pouvez simplement utiliser auto.
Dans le cas plus sophistiqué où vous souhaitez utiliser "auto" dans une classe ou une structure, je suggérerais d'utiliser un template avec decltype.
Par exemple, disons que vous utilisez la bibliothèque de quelqu'un d'autre et qu'elle a une variable appelée "unknown_var" et que vous voudriez la mettre dans un vecteur ou une structure, vous pouvez totalement faire ceci:
template <typename T>
struct my_struct {
int some_field;
T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector
J'espère que cela t'aides.
EDIT: Pour faire bonne mesure, voici le cas le plus complexe auquel je puisse penser: avoir une variable globale de type inconnu. Dans ce cas, vous aurez besoin de c ++ 14 et d'une variable de modèle.
Quelque chose comme ça:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
C'est toujours un peu fastidieux mais c'est aussi proche que possible des langages sans type. Assurez-vous simplement que chaque fois que vous faites référence à une variable de modèle, placez toujours la spécification de modèle ici.
Si vous avez besoin de faire une comparaison entre une classe et un type connu, par exemple:
class Example{};
...
Example eg = Example();
Vous pouvez utiliser cette ligne de comparaison:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
qui vérifie que le typeid
nom contient le type de chaîne (le nom de typeid a d'autres données mutilées, il est donc préférable de faire un s1.find(s2)
au lieu de ==
).
Vous pouvez certainement choisir typeid(x).name()
où x est le nom de la variable. Il renvoie en fait un pointeur const char vers le type de données. Maintenant, regardez le code suivant.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 36;
char c = 'A';
double d = 1.2;
if(*(typeid(n).name()) == 'i'){
cout << "I am an Integer variable" << endl;
}
if(*((char *) typeid(d).name()) == 'd'){
cout << "I am a Double variable" << endl;
}
if(*((char *) typeid(c).name()) == 'c'){
cout << "I am a Char variable" << endl;
}
return 0;
}
Remarquez comment le premier et le second fonctionnent tous les deux.
std::cout << "I'm a variable of type " << typeid(n).name()
. (reformulé pour éviter les artefacts / an, mais cela peut être corrigé avec une autre vérification). Même dans ce cas, si vous voulez absolument une comparaison, c'est tellement mieux à fairetypeid(n) == typeid(int)