2009-05-06 29 views
6

Manchmal muss ich den Typ eines Ausdrucks während der Programmierung in C oder C++ lernen. Manchmal gibt es eine gute IDE oder vorhandene Dokumentation, die mir hilft, aber manchmal nicht. Ich habe oft das Gefühl, ein solches Konstrukt könnte nützlich sein:Bestimmen des Typs eines Ausdrucks

void (*myFunc)(int); 
printf("%s", nameoftype(myFunc)); //"void (*)(int)" 
int i, unsigned int u; 
printf("%s", nameoftype(i+u)); //"unsigned int" 

Dies gilt insbesondere für C++; Denken Sie an Accessoren von const-Objekten - geben sie eine const-Referenz oder eine Kopie zurück? Denken Sie über dynamische Casts und Vorlagen nach.

Wie kann ich das tun? (d. h. lerne den Typ eines Ausdrucks)

Ich benutze GCC, aber soweit ich weiß, hat es keine solche Erweiterung. Ich bin also gespannt, wie Menschen dieses Problem lösen. (Sowohl Kompilierungszeit- als auch Runtime-Lösungen sind willkommen.)

Antwort

1

Wonach suchen Sie? Automatische Inferenz oder Suche nach dem Typ, so dass Sie eine Variable manuell korrekt deklarieren können? (Ihre eigenen Antworten sehen so aus, als wollten Sie die zweite haben). In diesem Fall betrachten Geordi mit:

<litb> make type pointer to function taking pointer to array of 10 int returning void 
<geordi> void (*)(int (*)[10]) 

<litb> geordi: { int a = -1; unsigned int b = 0; cout << ETYPE(a + b), ETYPE_DESC(a + b), (a + b); } 
<geordi> rvalue unsigned int, rvalue unsigned integer, 4294967295 

<litb> geordi: << TYPE_DESC(void (*)(int (*)[10])) 
<geordi> pointer to a function taking a pointer to an array of 10 integers and returning nothing 

Automatische Typinferenz ist derzeit nicht möglich, ohne Helfer Bibliotheken wie boost.typeof, die Compiler-Erweiterungen wie __typeof__ für GCC verwenden. Als nächstes wird C++ auto (mit anderer Semantik als der aktuelle) bekommen und kann das zusammen mit decltype tun, um den Typ eines Ausdrucks zu erhalten.

Wenn Sie mit dem Ausstieg aus lokalen Kontext leben können, können Sie immer eine Funktionsschablone wie folgt erstellen:

template<typename T> void f(T t) { /* ... */ } 
int main() { int a = -1; unsigned int b = 0; f(a + b); } 
+0

Entschuldigung, ich dachte, es wäre offensichtlich, dass ich nicht nach Typinferenz suchte. Obwohl ich mich darauf freue, einen neuen sphagetti C++ 0x Code mit automatischen Variablen zu sehen :) - Wow, ich hätte vergessen, dass Geordi Beschreibungen schreiben könnte. Ich werde mir die Implementierung ansehen. Danke auch für den KDevelop-Link. Es könnte eine Alternative zu Eclipse sein. – aib

+1

Geordi Link ist tot - hier ist der aktuelle Standort auf GitHub: https://github.com/Eelis/geordi – KarlC

2

C++ hat einen Operator typeid;

typeid(expression).name() 

würde einen implementierungsdefinierten Namen des Typs des Ausdrucks zurückgeben. Leider ist es normalerweise nicht lesbar.

+3

Wenn youare g ++ verwendet es ist der mangeled Namen. Sie können dann das Kommandozeilenwerkzeug 'C++ filt' verwenden, um es zu entmangeln. –

+0

Ah, ich habe nie C++ filt benutzt. Ich werde mich darum kümmern, danke. – aib

+0

Derzeit wird dieser Ansatz nicht empfohlen und sollte in einigen Fällen als veraltet betrachtet werden. Der Grund dafür, dass es Typ druckt, ist die Art der Ausgabe umständlich. Außerdem druckt es manchmal ungültigen Typ! Die genauen Beispiele werden im neuen "Effective Modern C++", Kapitel 1, Punkt 4, klar erläutert. – likern

13

Manchmal mache ich gerade:

int ***a = expression; 

und suchen Sie nach dem „<Ausdrucksart> nicht zu Zeiger auf^3 int zugewiesen werden kann“ Fehler. Dies scheint die portabelste Problemumgehung zu sein.

+1

Einige ältere C-Compiler erlauben dies jedoch. :-( –

+3

Ich erstelle eine Klasse 'FailAssign' und versuche dann einen Ausdruck einer Instanz der Klasse zuzuweisen. Auf diese Weise werden keine automatischen Konvertierungen ausgelöst (auch keine fehlerhaften). –

+2

Hmm, gute Idee.Mit meinem Weg kannst du einen Dreifachzeiger deklarieren! Wie oft kannst du das machen? :) – aib

1

Versuchen Sie Boost.Typeof, um zu sehen, ob es passt.

+0

Es scheint wie eine gute Lösung für Typ-Inferenz, aber ich habe kein Makro, das zu evaluieren, oder eine Funktion, die eine Zeichenfolge mit dem Typnamen zurückgibt. Man könnte jedoch hinzufügen, wie es zentrale REGISTER_() - Makros verwendet. – aib

Verwandte Themen