Comment récupérer le type de données d'une variable?

9

J'utilise Arduino et je voudrais savoir s'il existe une fonction qui renvoie le type de données d'une variable. Autrement dit, je voudrais exécuter quelque chose comme ceci:

// Note: 'typeof' is a sample function that should return the data type.
Serial.println(typeof(myVar));
user502052
la source
5
Pourquoi avez-vous besoin de faire ça? le type de la variable doit être connu depuis que vous l'avez déclaré
sachleen

Réponses:

15

Dans un programme C ++ typique, vous utiliseriez l' typeidopérateur, comme ceci:

std::cout << typeid(myVar).name();

Cependant, cela nécessite une fonction de compilation appelée RTTI (Runtime Type Information). Il est désactivé dans l'IDE Arduino, probablement parce qu'il a tendance à augmenter les besoins en mémoire d'exécution du programme.

Vous pouvez obtenir plus d'informations sur le coût des ressources ici: /programming/579887/how-expensive-is-rtti

Tout compilateur C ++ complet prendra certainement en charge RTTI. Si vous souhaitez essayer d'utiliser un IDE tiers (comme Eclipse avec le plugin Arduino), vous pouvez facilement l'activer. Mais cela ne vaut probablement pas la peine.


Alternative
Une solution plus performante (mais moins flexible) consisterait à utiliser une approche par classe de traits. Cela implique une méta-programmation de modèle génial:

// Generic catch-all implementation.
template <typename T_ty> struct TypeInfo { static const char * name; };
template <typename T_ty> const char * TypeInfo<T_ty>::name = "unknown";

// Handy macro to make querying stuff easier.
#define TYPE_NAME(var) TypeInfo< typeof(var) >::name

// Handy macro to make defining stuff easier.
#define MAKE_TYPE_INFO(type)  template <> const char * TypeInfo<type>::name = #type;

// Type-specific implementations.
MAKE_TYPE_INFO( int )
MAKE_TYPE_INFO( float )
MAKE_TYPE_INFO( short )

Vous pouvez ajouter des MAKE_TYPE_INFO(..)lignes pour le type de votre choix, y compris les noms des classes personnalisées. Vous pouvez ensuite l'utiliser comme ceci:

int myVar = 17;
Serial.println( TYPE_NAME(myVar) );

Tout ce que vous ne définissez pas en utilisant MAKE_TYPE_INFO(..)apparaîtra comme "unknown".

C'est quelque chose d'assez avancé là-dedans, donc je n'essaierai pas d'expliquer comment tout cela fonctionne ici. Il existe différents didacticiels sur le Web sur la programmation de modèles C ++ si vous êtes intéressé.

EDIT: Il convient de noter que l' typeofopérateur n'est pas C ++ standard, mais est pris en charge par quelques compilateurs, tels que GCC. Il s'agit essentiellement d'un ancien équivalent de decltype, qui apparaît dans la norme C ++ 11.

Peter Bloomfield
la source
réponse très informative et approfondie! apprécierait plus de ce genre
Omer
11

J'utilise une approche stupide simple ...

void types(String a){Serial.println("it's a String");}
void types(int a)   {Serial.println("it's an int");}
void types(char* a) {Serial.println("it's a char*");}
void types(float a) {Serial.println("it's a float");} 

Il s'agit du concept de polymorphismeplusieurs fonctions avec différents types de paramètres sont créées mais avec le même nom de fonction . Pendant l'exécution, la fonction correspondant au bon nombre d'arguments et de type (s) d'argument sera appelée. J'espère que cette explication vous aidera.

SnakeNET
la source
Pourriez-vous développer un peu votre réponse en expliquant brièvement comment cela fonctionne?
Greenonline
j'ai dû le réécrire à la main car le copier-coller a entraîné des problèmes que je ne comprenais pas. Après l'avoir retapée à la main, tout comme pour le croquis, cela a fonctionné comme un charme. Assez utile ...
novski