web-dev-qa-db-fra.com

Comment puis-je obtenir le type d'une variable?

En C++, comment trouve-t-on le type d'une variable?

93
0x499602D2

Vous pouvez utiliser l'opérateur typeid :

#include <typeinfo>
...
cout << typeid(variable).name() << endl;
116
Rich O'Kelly

Pour les assertions statiques, C++ 11 a introduit decltype, ce qui est très utile dans certains scénarios.

22
user2074102

Si vous avez une variable

int k;

Vous pouvez obtenir son type en utilisant

cout << typeid(k).name() << endl;

Voir le fil suivant sur SO: Question similaire

11
Amit

Généralement, vouloir trouver le type d'une variable en C++ n'est pas la bonne question. Cela a tendance à être quelque chose que vous emportez avec des langages procéduraux tels que C ou Pascal.

Si vous souhaitez coder différents comportements en fonction du type, essayez d’en savoir plus sur, par exemple. surcharge de fonction et héritage d'objet . Cela n’aura pas de sens immédiat le premier jour de votre C++, mais continuez comme ça.

9
Pontus Gagge

La principale différence entre C++ et Javascript est que C++ est un langage statique, alors que javascript est dynamique.

Dans les langages dynamiques typés, une variable peut contenir n'importe quoi, et son type est donné par la valeur qu'elle détient, moment par moment. Dans les langages à typage statique, le type d'une variable est déclaré et ne peut pas changer.

Il peut exister une répartition dynamique, une composition d'objet et des sous-types (héritage et fonctions virtuelles), ainsi qu'une répartition statique et une sur-typage (via le modèle CRTP), mais dans tous les cas, le type de la variable doit être connu du compilateur.

Si vous êtes en mesure de ne pas savoir ce que c'est ou pourrait être, c'est parce que vous avez conçu quelque chose car le langage a un système de type dynamique.

Si c'est le cas, vous feriez mieux de repenser votre conception, car elle se rend dans un pays qui n'est pas naturel pour la langue que vous utilisez (la plupart du temps comme aller sur une autoroute avec une chenille ou dans l'eau avec une voiture)

8
Emilio Garavaglia

Je crois que j'ai 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 mettre en cas particulier le 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 d'utiliser le polymorphisme, pour 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, comme le code utilise des modèles, l’instruction switch ci-dessous doit être résolue de manière statique en un seul bloc de code, ce qui permet d’optimiser tous les faux cas, AFAIK.

Prenons cet exemple, où nous pourrions 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 afin d'accéder au matériel, lequel utilisera le type myClassA ou myClassB. En cas d'incompatibilité, 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
}
5
Dan Truong

Je ne suis pas sûr si ma réponse aiderait.

La réponse courte est que vous n'avez pas vraiment besoin de vouloir connaître le type d'une variable pour l'utiliser.

Si vous devez donner un type à une variable statique, vous pouvez simplement utiliser auto.

Dans des cas plus sophistiqués où vous voulez utiliser "auto" dans une classe ou une structure, je suggérerais d'utiliser template avec decltype.

Par exemple, supposons que vous utilisiez la bibliothèque de quelqu'un d'autre et qu'elle contienne une variable appelée "unknown_var" et que vous souhaitiez la placer dans un vecteur ou une structure, vous pouvez totalement le faire:

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 typage. Assurez-vous simplement que chaque fois que vous référencez une variable de modèle, placez-y toujours la spécification de modèle.

3
gohongyi
#include <typeinfo>

...
string s = typeid(YourClass).name()
2
rad