¿Cómo recuperar el tipo de datos de una variable?


9

Estoy usando Arduino y me gustaría saber si hay una función que devuelve el tipo de datos de una variable. Es decir, me gustaría ejecutar algo como lo siguiente:

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

55
¿Por qué necesitas hacer esto? el tipo de la variable debe conocerse desde que la declaró
sachleen

Respuestas:


15

En un programa típico de C ++, usaría el typeidoperador, así:

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

Sin embargo, eso requiere una característica del compilador llamada Información de tipo de tiempo de ejecución (RTTI). Está deshabilitado en el IDE de Arduino, presumiblemente porque tiende a aumentar los requisitos de memoria de tiempo de ejecución del programa.

Puede obtener más información sobre el costo de los recursos aquí: /programming/579887/how-expensive-is-rtti

Sin embargo, cualquier compilador de C ++ con todas las funciones definitivamente admitirá RTTI. Si desea intentar usar un IDE de terceros (como Eclipse con el complemento Arduino), puede habilitarlo fácilmente. Sin embargo, probablemente no valga la pena solo por eso.


Alternativa
Una solución de mayor rendimiento (pero menos flexible) sería utilizar un enfoque de clase de rasgos. Esto implica una metaprogramación de plantilla original:

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

Puede agregar MAKE_TYPE_INFO(..)líneas para cualquier tipo que desee, incluidos los nombres de clases personalizadas. Entonces podría usarlo así:

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

Cualquier cosa que no defina usando MAKE_TYPE_INFO(..)aparecerá como "unknown".

Eso es algo bastante avanzado, así que no intentaré explicar cómo funciona todo aquí. Sin embargo, hay varios tutoriales en la web sobre programación de plantillas de C ++ si está interesado.

EDITAR: Vale la pena señalar que el typeofoperador no es C ++ estándar, pero es compatible con algunos compiladores, como GCC. Básicamente es un equivalente anterior de decltype, que aparece en el estándar C ++ 11.


respuesta muy informativa y exhaustiva! agradecería más de este tipo
Omer

11

Yo uso un enfoque estúpido 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");} 

Este es el concepto de polimorfismo donde se crean múltiples funciones con diferentes tipos de parámetros pero con el mismo nombre de función . Durante el tiempo de ejecución, se llamará a la función que coincida con el número correcto de argumentos y tipo (s) de argumento. Espero que esta explicación ayude.


¿Podría ampliar un poco su respuesta , explicando brevemente cómo funciona?
Greenonline

Tuve que reescribirlo a mano porque copiar y pegar condujo a problemas que no entendía. Después de volver a escribirlo a mano tal como es para el boceto, funcionó a las mil maravillas. Muy útil ...
novski
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.