Metafunktion zum Konvertieren eines Typs in eine ganze Zahl und umgekehrt

8

Der typeid erlaubt es jedem Typ zur Laufzeit einen eindeutigen std::type_index zuzuordnen. Ich möchte das gleiche tun, indem ich zwei Metafunktionen statisch verwende:

%Vor%

Gibt es eine Möglichkeit, das in C ++ 11 zu tun?

    
Vincent 11.12.2015, 18:26
quelle

3 Antworten

8

Hier ist eine mögliche Lösung, die mit GCC 5.2 und Clang 3.7 "funktioniert".

Ich benutze Filip Roséen Constexpr Meta-Container mit einigen kleinen Änderungen. Als T.C. wies darauf hin, dass dies in Zukunft schlecht gemacht sein könnte, Diese Lösung ist im Produktionscode völlig unangemessen, aber im Moment ist es ziemlich cool. Ich bin mir nicht einmal sicher, ob das zu 100% normkonform ist.

%Vor%

Die Änderungen, die ich am ursprünglichen Code vorgenommen habe:

%Vor%

Ich habe atch::meta_list::push geändert, um die Größe des Meta-Containers vor zurückzugeben. Ich habe einen Template-Parameter mit einem Standardargument verwendet, um sicherzustellen, dass die Größe vor dem Push berechnet wird.

%Vor%

Ich habe eine kleine decltype -Helferfunktion in atch::meta_list hinzugefügt, um alle diese abhängigen Namen zu verbergen.

Einige Testcodes:

%Vor%

Sowohl Clang als auch GCC geben eine Reihe von Warnungen aus, aber sie funktionieren beide!

Clang kompiliert, läuft und gibt aus:

  

Kodierung: 0, 1, 2, 3,

     

Decodierung: i, d, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIceEE, f,

GCC kompiliert, läuft und gibt aus:

  

Kodierung: 0, 1, 2, 3,

     

Decodierung: i, d, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIceEE, f,

Vielleicht wärst du besser mit einem Vorverarbeitungsschritt ...

    
TartanLlama 16.12.2015, 10:51
quelle
4

Es gibt mehr als nur Typen in C ++, die von size_t gezählt werden können.

Als Beweis:

%Vor%

Es gibt genau so viele bob<X> -Typen wie size_t -Werte.

%Vor%

Jetzt ist alice<bob<1>, bob<2>> ein gültiger Typ. So ist alice<alice<bob<1>> .

Es gibt viel mehr alice -Typen als bob -Typen.

Es gibt also keine Injektion aus der Menge von size_t -Werten in die Menge von Typen.

Daher muss jede solche Abbildung unvollständig sein, wenn sie bijektiv ist. Sie können nur eine Teilmenge von Typen auf size_t und wieder zurück abbilden.

Sie haben nicht angegeben, dass Sie nur mit einer Teilmenge von Typen umgehen möchten. Die Antwort ist also, dass Sie nicht tun können, was Sie gefragt haben.

Beachten Sie, dass std::type_index einfach ein hashbares, vergleichbares Objekt ist. Es ist kein "Index" wie ein ganzzahliger Wert.

    
Yakk 11.12.2015 19:48
quelle
0

Ich werde eine Teillösung geben, da ich nicht daran interessiert bin, all die unordentlichen Details auszuarbeiten. Verwenden Sie ein Makro, das ein Argument mit der gesamten Typdefinition übernimmt. Jetzt mache drei Dinge mit diesem Argument (es müssen Helfer-Makros sein):

  • Verwenden Sie das Argument, wie es ist, um den Typ zu definieren.
  • Übergeben Sie das an eine kryptografische Hash-Funktion angegebene Argument.
    • Die Ausgabe dieser Funktion wird eine ganze Zahl von einer Anzahl von Bits sein. Zweifellos, weil kryptografisch sicher ist, wird diese ganze Zahl größer sein als die eingebauten ganzzahligen Typen. Verwenden Sie statt type_id oder size_t oder whatnot Ihren eigenen Indextyp. es kann ein POD sein.
  • Der Wert dieser Hash-Funktion ist der magische Wert für die Definition von encode_type und decode_type .
    • Wegen der Beschränkung der Typen im Template-Argument müssen Sie möglicherweise die Adresse von constexpr storage verwenden, die den Hash-Wert enthält, um decode_type .
    • zu definieren

Das Grundprinzip ist hier derselbe, den Gödels Beweis seines Unvollständigkeitssatzes verwendet, nämlich dass eine Zeichenkette immer zwei Interpretationen hat, zuerst als Mitglied eines formalen Systems und zweitens als Zahl. (Der Kern des Beweises besteht übrigens darin, eine Art zu schaffen, über diese Zahl aus dem formalen System zu sprechen.)

Die Details der Verwendung von Werkzeugen, die in einer C ++ - Werkzeugkette leicht verfügbar sind, sind sicher unordentlich. Das Schlüsselelement, das es möglich macht, ist jedoch der Stringification-Operator # . Das ist analog zu der zweiten obigen Interpretation, die Definition nicht als Mitglied einer Sprache, sondern als "nur Daten".

    
eh9 15.12.2015 15:57
quelle