Как получить тип данных переменной?


9

Я использую Arduino, и я хотел бы знать, если есть функция, которая возвращает тип данных переменной. То есть я хотел бы запустить что-то вроде следующего:

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

5
Зачем тебе это нужно? тип переменной должен быть известен с момента ее объявления
sachleen

Ответы:


15

В типичной программе на C ++ вы бы использовали typeidоператор, например так:

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

Однако для этого требуется функция компилятора, которая называется Информация о типе времени выполнения (RTTI). Он отключен в Arduino IDE, по-видимому, потому что он увеличивает требования к памяти во время выполнения программы.

Вы можете получить больше информации о стоимости ресурса здесь: /programming/579887/how-exорого-is-rtti

Любой полнофункциональный компилятор C ++ определенно будет поддерживать RTTI. Если вы хотите попробовать использовать стороннюю IDE (например, Eclipse с плагином Arduino), вы можете легко включить ее. Это, вероятно, не стоит хлопот только для этого, хотя.


Альтернатива
Более эффективным (но менее гибким) решением было бы использование подхода класса признаков. Это включает в себя некоторые интересные шаблоны мета-программирования:

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

Вы можете добавить MAKE_TYPE_INFO(..)строки для любого типа, который вы хотите, в том числе имена пользовательских классов. Затем вы можете использовать это так:

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

Все, что вы не определили, MAKE_TYPE_INFO(..)будет отображаться как "unknown".

Это довольно продвинутые вещи, поэтому я не буду пытаться объяснить, как все это работает здесь. В Интернете есть различные учебники по программированию шаблонов на C ++, если вам это интересно.

РЕДАКТИРОВАТЬ: Стоит отметить, что typeofоператор не является стандартным C ++, но поддерживается несколькими компиляторами, такими как GCC. Это в основном более старый эквивалент decltype, который появляется в стандарте C ++ 11.


очень информативный и обстоятельный ответ! был бы признателен больше такого рода
Омер

11

Я использую простой глупый подход ...

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

Это концепция полиморфизма, когда создаются несколько функций с разными типами параметров, но с одинаковым именем функции . Во время выполнения будет вызвана функция, соответствующая правильному количеству аргументов и типам аргументов. Надеюсь, это объяснение поможет.


Не могли бы вы немного расширить свой ответ , кратко объясняя, как он работает?
Greenonline

я должен был переписать это вручную, потому что копирование вставило привело к проблемам, которые я не понимал. После перепечатывания его вручную, так же, как на эскизе, он работал как шарм. Весьма полезно ...
Новски
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.