@ Kariboo, ich habe Google verwendet und es hat mich hierher geschickt.
Michael Warner
Diese Frage ist so wie sie ist sehr unklar, und selbst nachdem man die verschiedenen Antworten gesehen hat; Es ist keineswegs klar, dass die Frage die akzeptierte Antwort sucht.
Die von zurückgegebenen Namen typeidsind 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++filtoder mit verschiedenen Online-Demanglern wie demangler.com .
Cincodenada
33
Für statische Zusicherungen wurde C ++ 11 eingeführt, decltypewas in bestimmten Szenarien sehr nützlich ist.
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).
Wenn sich in C ++ die Dynamik ändert, dann denke ich, wäre es großartig und typeof und parseInt, parseFloat-Funktionen werden ebenfalls nützlich sein, aber ich weiß nicht, warum C ++ - Hersteller es zum Beispiel zu schwierig machen! wer sagt, dass es gut ist, cout << "String" zu schreiben
Waqas Tahir
Entschlossenheit ist am besten !!!! #include <sstream> string str ("1912"); int strtointval; stringstream (str) >> strtointval;
Waqas Tahir
@ Waqas Äh, was? Die Leute, die sagen, dass es am besten ist, sind die Leute, die die Sprache definieren, und IMO haben sie so ziemlich das letzte Wort, wenn es darum geht - zum Beispiel gute Codierungspraktiken. Könnten Sie diesen Kommentar umformulieren, damit er sinnvoller ist?
Fund Monica Klage
Ich bin völlig anderer Meinung. Java, C #, PHP, Perl, Python usw. wurden in C und C ++ entwickelt und sind keine Raupen. (Wenn Sie eine Datenbankanwendung erstellen, um Variablentabellen aus 'unbekannten' Datenbanken zu öffnen, müssen Sie den Feldtyp auf 'sehr' dymanische Weise in das Variablenschema und umgekehrt steuern;))
TomeeNS
@TomeeNS: Nein. Sie sind geschrieben in C und C ++, nicht ausgelegt . Sie sind so konzipiert, dass sie ihre Arbeit erledigen. Sie haben einen dynamischen Typ, auch wenn C und C ++ selbst dies nicht tun. Das ist nichts Seltsames daran.
Emilio Garavaglia
8
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.
Nehmen wir an, Sie haben ein Klassenobjekt und ein Unterklassenbuch. Stellen Sie sich nun vor, Sie haben eine Box, in der viele Objekte gespeichert werden können, aber aus irgendeinem Grund möchten Sie alle darin enthaltenen Bücher auflisten. Das Überprüfen des Typs ist viel sauberer, dann muss eine Methode "Typ" zu Object hinzugefügt und dann in Buch überschrieben werden, um so etwas wie "Buch" zurückzugeben
Paulo Cesar
Wie bei jeder Regel gibt es Ausnahmen (daher meine "normalerweise"!), Und Container erhöhen tendenziell die Komplexität der Typentheorie. Ich habe Container mit polymorphen Objekten noch nie überfordert… in den meisten Fällen reichen einheitliche Containertypen mit Vorlagen aus und sind viel sauberer.
Pontus Gagge
Verwenden Sie keine Vorlagen?
Bryan Grace
6
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)){casetypeid(myClassA):// handle that casebreak;casetypeid(myClassB):// handle that casebreak;casetypeid(uint32_t):// handle that casebreak;default:// handle that case}
TypeId: Ich konnte typeid () auf Arduino nicht verwenden. Außerdem ist typeid () eine Laufzeitprüfung , keine Kompilierungszeit, sodass sie nicht zum Generieren von optimiertem Code verwendet werden kann.
Dan Truong
1
Ja, nein, das macht nicht das, was du gedacht hast. typeidkann 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 variableRichtig, was Sie also wirklich wollen, ist statischer Polymorphismus über das CRTP-Idiom. Genau das erreicht man.
underscore_d
4
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.
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.
typeidHiermit 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>usingnamespace 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;}return0;}
Beachten Sie, wie erstens und zweitens beide funktionieren.
Das Erkennen des Typs am ersten Zeichen ist eine sehr schlechte Idee.
Dmitry Kuzminov
Könnten Sie bitte genauer Dmitry sein? Ich habe Ihren Standpunkt hier nicht verstanden.
Pikachu
Dies kann nur auf verkürzt werden 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)
Antworten:
Sie können den Operator typeid verwenden :
quelle
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 wiec++filt
oder mit verschiedenen Online-Demanglern wie demangler.com .Für statische Zusicherungen wurde C ++ 11 eingeführt,
decltype
was in bestimmten Szenarien sehr nützlich ist.quelle
Wenn Sie eine Variable haben
Sie können seinen Typ mit erhalten
Siehe den folgenden Thread zu SO: Ähnliche Frage
quelle
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).
quelle
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.
quelle
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.
quelle
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:
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:
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.
quelle
quelle
Wenn Sie einen Vergleich zwischen einer Klasse und einem bekannten Typ durchführen müssen, zum Beispiel:
Sie können diese Vergleichszeile verwenden:
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, eines1.find(s2)
anstelle von auszuführen==
).quelle
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.Beachten Sie, wie erstens und zweitens beide funktionieren.
quelle
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)