Wie findet man in C ++ den Typ einer Variablen?
Wie findet man in C ++ den Typ einer Variablen?
Antworten:
Sie können den Operator typeid verwenden :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
Ganzzahl auf Ihrem Compiler. Die zurückgegebenen Namen werden vom Standard nicht angegeben.
typeid
sind sehr abgekürzt, compilerspezifisch und nicht für den menschlichen Verzehr bestimmt. Sie können sie "entwirren" (das ist der eigentliche Begriff!), Entweder im Code mit so etwas wie gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , mit Befehlszeilenprogrammen wie c++filt
oder mit verschiedenen Online-Demanglern wie demangler.com .
Wenn Sie eine Variable haben
int k;
Sie können seinen Typ mit erhalten
cout << typeid(k).name() << endl;
Siehe den folgenden Thread zu SO: Ähnliche Frage
Der Hauptunterschied zwischen C ++ und Javascript besteht darin, dass C ++ eine statisch typisierte Sprache ist, während Javascript dynamisch ist.
In dynamisch typisierten Sprachen kann eine Variable alles enthalten, und ihr Typ wird durch den Wert angegeben, den sie von Moment zu Moment enthält. In statisch typisierten Sprachen wird der Typ einer Variablen deklariert und kann nicht geändert werden.
Es kann eine dynamische Dispatch- und Objektzusammensetzung und -untertypisierung (Vererbung und virtuelle Funktionen) sowie eine statische Dispatching- und Supertypisierung (über das Vorlagen-CRTP) geben, aber in jedem Fall muss der Typ der Variablen dem Compiler bekannt sein.
Wenn Sie in der Lage sind, nicht zu wissen, was es ist oder sein könnte, liegt dies daran, dass Sie etwas entworfen haben, da die Sprache ein dynamisches Typsystem hat.
Wenn dies der Fall ist, sollten Sie Ihr Design besser überdenken, da es in ein Land geht, das für die Sprache, die Sie verwenden, nicht natürlich ist (meistens wie auf einer Autobahn mit einer Raupe oder im Wasser mit einem Auto).
Normalerweise ist es die falsche Frage, den Typ einer Variablen in C ++ zu finden. Es ist etwas, das Sie aus prozeduralen Sprachen wie C oder Pascal mitnehmen.
Wenn Sie je nach Typ unterschiedliche Verhaltensweisen codieren möchten, versuchen Sie, z. B. Funktionsüberladung und Objektvererbung kennenzulernen . Dies ist an Ihrem ersten Tag in C ++ nicht sofort sinnvoll, aber bleiben Sie dabei.
Ich glaube, ich habe einen gültigen Anwendungsfall für die Verwendung von typeid (), genauso wie es für die Verwendung von sizeof () gültig ist. Für eine Vorlagenfunktion muss der Code basierend auf der Vorlagenvariablen als Sonderfall verwendet werden, damit ich maximale Funktionalität und Flexibilität bieten kann.
Es ist viel kompakter und wartbarer als die Verwendung von Polymorphismus, eine Instanz der Funktion für jeden unterstützten Typ zu erstellen. Selbst in diesem Fall könnte ich diesen Trick verwenden, um den Hauptteil der Funktion nur einmal zu schreiben:
Da der Code Vorlagen verwendet, sollte die folgende switch-Anweisung statisch in nur einen Codeblock aufgelöst werden, um alle falschen Fälle, AFAIK, zu optimieren.
Betrachten Sie dieses Beispiel, in dem wir möglicherweise eine Konvertierung durchführen müssen, wenn T ein Typ gegen einen anderen ist. Ich verwende es für die Klassenspezialisierung, um auf Hardware zuzugreifen, bei der die Hardware entweder den Typ myClassA oder myClassB verwendet. Bei einer Nichtübereinstimmung muss ich Zeit damit verbringen, die Daten zu konvertieren.
switch ((typeid(T)) {
case typeid(myClassA):
// handle that case
break;
case typeid(myClassB):
// handle that case
break;
case typeid(uint32_t):
// handle that case
break;
default:
// handle that case
}
typeid
kann per Definition einfach keine statische Überprüfung zur Kompilierungszeit sein, daher erleichtert dies keine Optimierung. For a template function, I need to special case the code based on the template variable
Richtig, was Sie also wirklich wollen, ist statischer Polymorphismus über das CRTP-Idiom. Genau das erreicht man.
Ich bin mir nicht sicher, ob meine Antwort helfen würde.
Die kurze Antwort lautet: Sie müssen / möchten den Typ einer Variablen nicht wirklich kennen, um sie verwenden zu können.
Wenn Sie einer statischen Variablen einen Typ zuweisen müssen, können Sie einfach auto verwenden.
In einem komplexeren Fall, in dem Sie "auto" in einer Klasse oder Struktur verwenden möchten, würde ich vorschlagen, eine Vorlage mit decltype zu verwenden.
Angenommen, Sie verwenden die Bibliothek eines anderen Benutzers und sie hat eine Variable namens "unknown_var". Sie möchten sie in einen Vektor oder eine Struktur einfügen. Sie können dies vollständig tun:
template <typename T>
struct my_struct {
int some_field;
T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector
Hoffe das hilft.
EDIT: Zum guten Teil ist hier der komplexeste Fall, den ich mir vorstellen kann: eine globale Variable unbekannten Typs. In diesem Fall benötigen Sie c ++ 14 und eine Vorlagenvariable.
Etwas wie das:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
Es ist immer noch etwas langweilig, aber es ist so nah wie möglich an typenlosen Sprachen. Stellen Sie einfach sicher, dass Sie immer die Vorlagenspezifikation dort einfügen, wenn Sie auf eine Vorlagenvariable verweisen.
Wenn Sie einen Vergleich zwischen einer Klasse und einem bekannten Typ durchführen müssen, zum Beispiel:
class Example{};
...
Example eg = Example();
Sie können diese Vergleichszeile verwenden:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
typeid
Hiermit wird überprüft, ob der Name den Zeichenfolgentyp enthält ( der Name der Typ-ID enthält andere entstellte Daten, daher ist es am besten, eine s1.find(s2)
anstelle von auszuführen ==
).
Sie können definitiv festlegen, typeid(x).name()
wo x der Variablenname ist. Es gibt tatsächlich einen const char-Zeiger auf den Datentyp zurück. Schauen Sie sich nun den folgenden Code an.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 36;
char c = 'A';
double d = 1.2;
if(*(typeid(n).name()) == 'i'){
cout << "I am an Integer variable" << endl;
}
if(*((char *) typeid(d).name()) == 'd'){
cout << "I am a Double variable" << endl;
}
if(*((char *) typeid(c).name()) == 'c'){
cout << "I am a Char variable" << endl;
}
return 0;
}
Beachten Sie, wie erstens und zweitens beide funktionieren.
std::cout << "I'm a variable of type " << typeid(n).name()
. (umformuliert, um ein / ein Artefakt zu verhindern, aber das kann mit einer anderen Prüfung behoben werden). Selbst dann, wenn Sie unbedingt einen Vergleich wünschen, ist es viel bessertypeid(n) == typeid(int)