Wie rufe ich den Datentyp einer Variablen ab?

8

Ich verwende Arduino und möchte wissen, ob es eine Funktion gibt, die den Datentyp einer Variablen zurückgibt. Das heißt, ich möchte Folgendes ausführen:

// Note: 'typeof' is a sample function that should return the data type.
Serial.println(typeof(myVar));
user502052
quelle
5
Warum müssen Sie das tun? Der Typ der Variablen sollte bekannt sein, da Sie sie deklariert haben
Sachleen

Antworten:

14

In einem typischen C ++ - Programm würden Sie den typeidOperator folgendermaßen verwenden:

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

Dies erfordert jedoch eine Compilerfunktion namens Runtime Type Information (RTTI). Es ist in der Arduino IDE deaktiviert, vermutlich weil es dazu neigt, den Laufzeitspeicherbedarf des Programms zu erhöhen.

Weitere Informationen zu den Ressourcenkosten erhalten Sie hier: /programming/579887/how-expensive-is-rtti

Jeder voll funktionsfähige C ++ - Compiler wird RTTI jedoch definitiv unterstützen. Wenn Sie versuchen möchten, eine IDE eines Drittanbieters (z. B. Eclipse mit dem Arduino-Plugin) zu verwenden, können Sie diese problemlos aktivieren. Es ist wahrscheinlich nicht die Mühe wert, nur dafür.


Alternative
Eine leistungsstärkere (aber weniger flexible) Lösung wäre die Verwendung eines Merkmalsklassenansatzes. Dies beinhaltet einige funky Template-Meta-Programmierung:

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

Sie können MAKE_TYPE_INFO(..)Zeilen für jeden gewünschten Typ hinzufügen , einschließlich der Namen benutzerdefinierter Klassen. Sie könnten es dann so verwenden:

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

Alles, was Sie nicht mit definieren, MAKE_TYPE_INFO(..)wird als angezeigt "unknown".

Das sind ziemlich fortgeschrittene Sachen, also werde ich nicht versuchen zu erklären, wie das alles hier funktioniert. Es gibt verschiedene Tutorials im Web über die Programmierung von C ++ - Vorlagen, wenn Sie interessiert sind.

BEARBEITEN: Es ist erwähnenswert, dass der typeofOperator kein Standard-C ++ ist, sondern von einigen Compilern wie GCC unterstützt wird. Es ist im Grunde ein älteres Äquivalent von decltype, das im C ++ 11-Standard erscheint.

Peter Bloomfield
quelle
sehr informative und gründliche Antwort! würde mich über mehr dieser Art
freuen
11

Ich benutze einen einfachen dummen Ansatz ...

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

Dies ist das Konzept des Polymorphismus, bei dem mehrere Funktionen mit unterschiedlichen Parametertypen mit demselben Funktionsnamen erstellt werden . Zur Laufzeit wird die Funktion aufgerufen, die der richtigen Anzahl von Argumenten und Argumenttypen entspricht. Hoffe diese Erklärung hilft.

SnakeNET
quelle
Könnten Sie Ihre Antwort ein wenig erweitern und kurz erklären, wie es funktioniert?
Greenonline
Ich musste es von Hand umschreiben, weil das Kopieren und Einfügen zu Problemen führte, die ich nicht verstand. Nachdem es wie bei der Skizze von Hand erneut eingegeben wurde, wirkte es wie ein Zauber. Ganz nützlich ...
Novski