Come recuperare il tipo di dati di una variabile?


9

Sto usando Arduino e vorrei sapere se esiste una funzione che restituisce il tipo di dati di una variabile. Cioè, vorrei eseguire qualcosa come il seguente:

// Note: 'typeof' is a sample function that should return the data type.
Serial.println(typeof(myVar));

5
Perché hai bisogno di fare questo? il tipo di variabile dovrebbe essere noto da quando l'hai dichiarata
sachleen,

Risposte:


15

In un tipico programma C ++, useresti l' typeidoperatore, in questo modo:

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

Tuttavia, ciò richiede una funzione del compilatore chiamata Runtime Type Information (RTTI). È disabilitato nell'IDE di Arduino, presumibilmente perché tende ad aumentare i requisiti di memoria di runtime del programma.

Puoi ottenere maggiori informazioni sul costo delle risorse qui: /programming/579887/how-expensive-is-rtti

Tuttavia, qualsiasi compilatore C ++ completo supporterà sicuramente RTTI. Se si desidera provare a utilizzare un IDE di terze parti (come Eclipse con il plug-in Arduino), è possibile abilitarlo facilmente. Probabilmente non vale la pena solo per questo.


Alternativa
Una soluzione più performante (ma meno flessibile) sarebbe quella di utilizzare un approccio di classe tratti. Ciò comporta alcune meta-programmazioni di template funky:

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

È possibile aggiungere MAKE_TYPE_INFO(..)righe per qualsiasi tipo desiderato, inclusi i nomi delle classi personalizzate. È quindi possibile utilizzarlo in questo modo:

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

Tutto ciò che non definisci usando MAKE_TYPE_INFO(..)verrà visualizzato come "unknown".

Ci sono alcune cose abbastanza avanzate, quindi non proverò a spiegare come funziona tutto qui. Esistono vari tutorial sul web sulla programmazione dei modelli C ++ se sei interessato.

EDIT: Vale la pena notare che l' typeofoperatore non è C ++ standard, ma è supportato da alcuni compilatori, come GCC. È fondamentalmente un equivalente più vecchio di decltype, che appare nello standard C ++ 11.


risposta molto istruttiva e approfondita! apprezzerei di più di questo tipo
Omer, il

11

Uso un semplice approccio stupido ...

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");} 

Questo è il concetto di polimorfismo in cui vengono create più funzioni con diversi tipi di parametri ma con lo stesso nome di funzione . Durante il runtime, verrà chiamata la funzione che corrisponde al giusto numero di argomenti e tipi di argomento. Spero che questa spiegazione sia d'aiuto.


Potresti espandere leggermente la tua risposta , spiegando brevemente come funziona?
Greenonline,

ho dovuto riscriverlo a mano perché copia incolla ha portato a problemi che non capivo. Dopo averlo riscritto a mano come per lo schizzo, ha funzionato come un incantesimo. Molto utile ...
novski
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.