Como recuperar o tipo de dados de uma variável?

9

Estou usando o Arduino e gostaria de saber se existe uma função que retorna o tipo de dados de uma variável. Ou seja, eu gostaria de executar algo como o seguinte:

// Note: 'typeof' is a sample function that should return the data type.
Serial.println(typeof(myVar));
user502052
fonte
5
Por que você tem que fazer isso? o tipo da variável deve ser conhecido desde que declarou
sachleen

Respostas:

15

Em um programa C ++ típico, você usaria o typeidoperador da seguinte maneira:

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

No entanto, isso requer um recurso do compilador chamado Runtime Type Information (RTTI). Ele está desativado no IDE do Arduino, provavelmente porque tende a aumentar os requisitos de memória de tempo de execução do programa.

Você pode obter mais informações sobre o custo do recurso aqui: /programming/579887/how-expensive-is-rtti

Qualquer compilador C ++ com recursos completos definitivamente suportará RTTI. Se você quiser tentar usar um IDE de terceiros (como o Eclipse, com o plug-in do Arduino), poderá ativá-lo facilmente. Provavelmente não vale a pena o aborrecimento apenas por isso.


Alternativa
Uma solução de melhor desempenho (mas menos flexível) seria usar uma abordagem de classe de características. Isso envolve alguma meta-programação de modelos:

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

Você pode adicionar MAKE_TYPE_INFO(..)linhas para qualquer tipo que desejar, incluindo os nomes de classes personalizadas. Você poderia usá-lo assim:

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

Tudo o que você não definir usando MAKE_TYPE_INFO(..)será exibido como "unknown".

Isso é algo bastante avançado, então não tentarei explicar como tudo funciona aqui. Existem vários tutoriais na Web sobre programação de modelos C ++, se você estiver interessado.

EDIT: Vale a pena notar que o typeofoperador não é C ++ padrão, mas é suportado por alguns compiladores, como o GCC. É basicamente um equivalente antigo decltype, que aparece no padrão C ++ 11.

Peter Bloomfield
fonte
resposta muito informativa e completa! gostaria de receber mais deste tipo
Omer
11

Eu uso uma abordagem estúpida simples ...

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 é o conceito de polimorfismo em que várias funções com diferentes tipos de parâmetros são criadas, mas com o mesmo nome de função . Durante o tempo de execução, a função que corresponde ao número certo de argumentos e aos tipos de argumentos será chamada. Espero que esta explicação ajude.

SnakeNET
fonte
Você poderia expandir um pouco sua resposta , explicando brevemente como ela funciona?
Greenonline
tive que reescrevê-lo manualmente porque copiar e colar levou a problemas que não entendi. Depois de redigitá-lo à mão, exatamente como no esboço, funcionou como um encanto. Muito útil ...
novski