simulieren die Kompilierzeit-Reflektion in C ++

8

Ich habe eine folgende Struktur:

%Vor%

Ich möchte eines der Mitglieder nach dem Stringnamen in constexpr way auswählen, wie

%Vor%

getMember ist constexpr function / struct / macros / was auch immer in Frage und Ausdruck sollte (ich will es sein) in einfache auto& member = instance.firstMember; optimiert werden. Mein Wunsch ist hier in der Lage zu sein, getMember von einer anderen constexpr -Funktion aufzurufen, die wiederum den Computernamen eines bestimmten Mitglieds sind - & gt; eine Art Kompilierzeit Reflexion.

Ich weiß, es gibt keine Reflexion in C ++, daher ist es in Ordnung, sich einige Namen von Mitgliedern der fraglichen Struktur anzueignen, wie zB:

%Vor%

Alles, was ich will, ist, diese Kompilierzeitoptimierung zu haben und in der Laufzeit nichts zu tun. Ist das in C ++ 11 möglich und wie?

    
hate-engine 12.12.2012, 00:23
quelle

1 Antwort

13

Wie in den Kommentaren erwähnt, sehen Sie sich zuerst BOOST_FUSION_ADAPT_STRUCT (und Freunde) an:

%Vor%

Dadurch wird Ihre Data -Struktur in eine Sequenz umgewandelt, die von Fusion verwendet werden kann:

%Vor%

Dies druckt "firstData" . Ändern Sie den Index so, dass er sich auf die Elemente in der Reihenfolge bezieht.

Dort können wir jetzt zur Zeit der Kompilierung auf Mitglieder verweisen, indem wir eine Nummer verwenden. Aber du wolltest einen Namen. Auch in den Kommentaren bemerkt, ist die Verarbeitung von Zeichenfolgen eine Laufzeitfunktion ... fast. C ++ 11 gibt uns constexpr .

Es ist ein bisschen schwierig, aber letztlich sieht es so aus:

%Vor%

Es sieht unheimlich aus, aber es ist lesbar, wenn Sie sich die Zeit nehmen, es auseinander zu nehmen.

Wir müssen unsere eigenen Makros einführen, um Zugriff auf die Membernamen mit konstantem Ausdruck zu erhalten; Das meiste Hässliche kommt von der Verarbeitung von Boost.Preprocessor-Listen. Obwohl Fusion die Namen auch während der Anpassung aufzeichnet (siehe boost::fusion::extension::struct_member_name ), sind sie nicht als constexpr gekennzeichnet, sind also leider nicht für uns nutzbar.

Dies ergibt:

%Vor%

Was ich denke, ist nah an dem, was Sie gesucht haben.

Aber denken Sie daran, das ist vielleicht nicht alles notwendig: Boost.Fusion hat vielleicht schon, was Sie brauchen. Es lebt in dem Bereich zwischen reinem Kompilier-Zeugs (Boost.MPL) und normalem Laufzeit-Zeug; Passen Sie Ihre Struktur an und Sie können bereits Dinge wie iterieren ( boost::fusion::for_each ).

    
GManNickG 15.12.2012, 18:41
quelle

Tags und Links