Ich möchte verschiedene Datentypen in C++ mit eindeutigen deterministischen Namen erzeugen. Zum Beispiel:einzigartiger synthetisierter Name
struct struct_int_double { int mem0; double mem1; };
Derzeit mein Compiler synthetisiert Namen unter Verwendung eines Zählers, was bedeutet, die Namen nicht übereinstimmen, wenn die gleichen Datentyp in verschiedenen Übersetzungseinheiten zu kompilieren.
Hier ist, was nicht funktioniert:
Mit dem ABI mangled_name Funktion. Denn es hängt schon von Strukturen ab, die eindeutige Namen haben. Könnte in C++ 11-konformem ABI funktionieren, indem man vorgibt, dass struct anonym ist?
Vorlagen z. B. struct2, da Vorlagen nicht mit rekursiven Typen arbeiten.
Eine komplette Mangling. Denn es gibt Namen, die Art und Weise zu lang sind (Hunderte von Zeichen!)
Neben einem globalen Register (igitt!) Das einzige, was ich ist denken kann, zuerst eine einzigartige lange verstümmelten Namen zu erstellen, und dann Verwenden Sie eine Digest- oder Hash-Funktion, um sie zu verkürzen (und hoffen, dass es keine Konflikte gibt).
Problem: Bibliotheken erzeugen, die aufgerufen werden können, wenn die Typen anonym sind, zB Tupel, Summenarten, Funktionstypen.
Irgendwelche anderen Ideen?
EDIT: Zusätzliche Beschreibung des rekursiven Typs Problem. Erwägen Sie, eine verknüpfte Liste wie folgt zu definieren:
template<class T>
typedef pair<list<T>*, T> list;
Dies ist tatsächlich, was erforderlich ist. Es funktioniert nicht aus zwei Gründen: Erstens können Sie keine typedef Vorlage. [NEIN, Sie können KEINE Template-Klasse mit einem typedef verwenden, es funktioniert nicht] Zweitens können Sie die list * nicht als Argument übergeben, weil sie noch nicht definiert ist. In C ohne Polymorphismus können Sie es tun:
struct list_int { struct list_int *next; int value; };
Es gibt mehrere Workarounds. Für diese insbesondere Problem können Sie eine Variante des Barton-Nackman-Trick verwenden, aber es verallgemeinert nicht.
Es gibt eine allgemeine Problemumgehung, die mir zuerst von Gabrielle des Rois gezeigt wurde, mit einer Vorlage mit offener Rekursion und dann einer Teilspezialisierung, um sie zu schließen. Aber das ist extrem schwierig zu generieren und wäre wahrscheinlich nicht lesbar, selbst wenn ich herausfinden könnte, wie es geht.
Es gibt ein anderes Problem, Varianten auch richtig zu machen, aber das ist nicht direkt verwandt (es ist nur schlimmer wegen der dummen Einschränkung gegen die Erklärung von Gewerkschaften mit konstruierbaren Typen).
Daher verwendet mein Compiler einfach normale C-Typen. Es muss irgendwie mit Polymorphie umgehen: Einer der Gründe für das Schreiben war, die Probleme des C++ - Systems einschließlich der Templates zu umgehen. Dies führt dann zu dem Namensproblem.
Was ist los mit 'std :: tuple'? (Oder 'std :: tr1 :: tuple') Was wollen Sie eigentlich hier erreichen? –
Was ist los mit '.get()' anstelle von '.memN'? –
@Billy: Es gibt kein std :: tuple (jedenfalls in C++ 98). Wenn C++ 11 dies hat und es eine Vorlage ist, wird es nicht funktionieren (Vorlagen können nicht mit rekursiven Typen umgehen), und ich würde es ungern benutzen, da mein aktuelles g ++ auf OSX nicht viel Unterstützung von C++ 11 hat (unglücklich). – Yttrill