Ich habe eine Template-Klasse erstellt, die einen Typ in einen String umwandelt, der sie beschreibt, zB typeinfo<int(*)()>::name()
gibt die Zeichenkette "int(*)()"
(bis zu Leerzeichen) zurück. Anfangs hatte ich Tonnen von Sonderfällen, um die Tatsache zu umgehen, dass typeid(...).name()
Referenz-Qualifier und Top-Level-CV-Qualifiers streifte, aber dann erinnerte ich mich, dass die Weitergabe eines Typs als Template-Parameter diese beibehalten würde. Also, mit dem ABI-Header, endete ich mit so etwas:
Dies kompiliert und arbeitet (fast) perfekt in GCC (4.8). GCC unterstützt jedoch nicht die Ref-Qualifier auf Member-Funktionen, also habe ich es auch in Clang (3.2) versucht, um zu sehen, ob es funktioniert. Es tut es nicht. Es kompiliert gut und wird ohne Problem ausgeführt, aber die meisten Vorlagennamen werden nicht abgerufen, und auch nicht die ref-qualifizierten Member-Funktionen.
Hier ist die GCC-Ausgabe von ideone (der Code wurde leicht optimiert, da die GCC-Version von ideone keine nullptr- oder Alias-Deklarationen unterstützt) . Beachten Sie das fehlende const-Qualifikationsmerkmal im Funktionsparameter. Das ist das Einzige, was nicht so funktioniert hat, wie ich es von GCC erwartet hatte. Dasselbe gilt auch für Clang, was nicht besonders überraschend ist. (Überraschend ist, dass es überhaupt fehlt, nicht dass GCC und Clang darauf konsistent sind.)
Leider konnten beim Übersetzen und Ausführen mit Clang die variantenbasierten Vorlagen nicht abgefragt werden. Zum Beispiel wurde J auf 1JIJiEE
anstatt auf 1JIIiEE
, das GCC ausgewählt hat, verändert.
Ausgewählte Ausgabe von clang (zeigt nur diejenigen an, die nicht funktioniert haben)
%Vor%Hat jemand eine Idee, wie das gelöst werden könnte? Ist es ein Bug im Klirren? (Oder vielleicht ein Fehler in GCC?) Mein erster Verdacht war eine Versionsinkompatibilität zwischen der C ++ - ABI, die mit meinem Code verknüpft ist, und der C ++ - ABI, die clang verwendet. Die Tatsache, dass das Problem nur bei neuen C ++ 11-Funktionen auftritt (Ref-Qualifikationsmerkmale und variadische Vorlagen für Mitgliedsfunktionen), scheint diesen Verdacht zu unterstützen ... obwohl R-Wert-Referenzen (zum Beispiel) kein Problem haben.
Falls es relevant ist, bin ich auf Mac OSX Lion und GCC 4.8 und clang 3.2 wurden von MacPorts installiert. Ich verwende die folgenden Befehle zum Kompilieren:
%Vor% Das isystem-Flag scheint erforderlich zu sein, damit callg die libc ++ - Header finden kann (was notwendig war, als ich <type_traits>
für die kompliziertere Version davon verwendete). Ohne es kann es nicht <iostream>
finden.
(Als zusätzliche Anmerkung betrifft dieses Problem auch die kompliziertere Version, da Klassennamen - wahrscheinlich nicht überraschend - nicht zu den Spezialisierungen für komplizierte Typen gehören und daher nur den ABI-Demangle-Aufruf verwenden.)
(Auch als Nebenbemerkung bin ich neugierig auf die Portabilität von diesem. Ich weiß, dass es in MSVC nicht notwendig ist, da das den unmigrierten Namen von typeid(...).name()
zurückgibt, aber abgesehen davon ...)