Frage

Aufteilung dieser Frage zu meiner Frage bezüglich Anhang an CPP -Makros:

Hat jemand hier das benutzt Boost.Proprocessor Die Datentypen der Bibliothek, um so etwas wie die X-Macro zu implementieren?

War es hilfreich?

Lösung

Ich habe nur nachgeschlagen, was für ein X-macro soll sein und ich glaube, ich habe so etwas getan, was du verlangst.

Ich wollte die Serialisierung für eine Reihe ziemlich ähnlicher Klassen einfach und schnell unterstützen. Das Problem, das ich hatte, ist, dass ich einige Laufzeitinformationen (ein INT) in einen Kompilierungszeittyp (eine Klasse) umwandeln musste, um meine Serialisierung durchzuführen. Ich hätte ein paar Fallanweisungen schreiben können, um den Job zu erledigen, aber das würde bedeuten, dass ich jedes Mal mehrere Funktionen aktualisieren muss, wenn ich eine Klasse hinzufügen wollte.

Um dieses Problem zu umgehen, habe ich zuerst definiert eine Sequenz von Tupel mit der Zuordnung enthalten:

#define WIN_MESSAGE_TYPE_SEQ \
    ((EM_REPLACESEL, em_replacesel))((WM_CHAR, wm_char)) //...

Die oberen Fallnamen sind definiert, die eine INT enthält, und die unteren Fallnamen sind Klassen, die ich woanders definiert habe.

Ich kann diese Sequenz dann in Verbindung mit einigen der von den verwenden Präprozessoren steigern Um alle möglichen Code für mich zu generieren. Um beispielsweise eine Forward -Erklärung der Klassen zu erhalten, kann ich das einfach tun:

#define WIN_MESSAGE_TYPE_BUILD_MACRO(r, _data_, _elem_) \
    class BOOST_PP_TUPLE_ELEM(2,1,_elem_);

BOOST_PP_SEQ_FOR_EACH(WIN_MESSAGE_TYPE_BUILD_MACRO, BOOST_PP_NIL, WIN_MESSAGE_TYPE_SEQ)

#undef WIN_MESSAGE_TYPE_BUILD_MACRO

Um die Laufzeit für die Zusammenstellung von Zeitzuordnung zu erstellen, generiere ich eine Reihe von Fallanweisungen wie folgt:

#define WIN_MESSAGE_TYPE_BUILD_MACRO(r, _data_, _elem_) \
    case BOOST_PP_TUPLE_ELEM(2,0,_elem_): return win_message_serializer<BOOST_PP_TUPLE_ELEM(2,1,_elem_)>::serialize(msg, o_arch);

template <typename Archive>
void serialize_win_message (p_win_message_base msg, Archive& o_arch) {
    message_type_t message_type = msg->type();

    switch (message_type) {

    // This will generate a series of case statement for each message type that will invoke
    // the serializer for the correct types.
    BOOST_PP_SEQ_FOR_EACH(WIN_MESSAGE_TYPE_BUILD_MACRO, BOOST_PP_NIL, WIN_MESSAGE_TYPE_SEQ)

    default: //...
    };
}

#undef WIN_MESSAGE_TYPE_BUILD_MACRO

Der gesamte Code beinhaltet einiges mehr als das, aber dies sollte Ihnen immer noch eine Vorstellung davon geben, wie Sie mit den Boost -Präprozessoren Code generieren können. In meinem Beispiel kann ich schnell und einfach die Serialisierungsunterstützung für eine Klasse hinzufügen, indem ich einfach meine Sequenz aktualisiere.

Beachten Sie, dass die Verwendung des Boost -Präprozessors keinen sehr lesbaren Code erzeugt, sodass ich versuche, das für jedes Makro verwendete Makro so einfach wie möglich zu halten. Ich wäre auch nicht überrascht, wenn jemand irgendwo eine elegantere Lösung für dieses Problem hat. Dies ist genau das, was ich mir für ein persönliches Projekt ausgedacht habe, bei dem mir die zusätzliche Komplexität nichts ausmacht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top