Вопрос

Разделить это от моего вопроса относительно Добавление к макросам CPP:

Кто -нибудь здесь использовал Boost.preprocessor Типы данных библиотеки для реализации чего-то вроде X-Macro?

Это было полезно?

Решение

Я только что посмотрел, что X-Macro должен быть, и я думаю, что я сделал что -то вроде того, о чем вы просите.

Что я хотел сделать, так это легко и быстро поддерживать сериализацию для серии довольно похожих классов. Проблема, которая у меня была, заключается в том, что мне пришлось преобразовать некоторую информацию о времени выполнения (Int) в тип времени компиляции (класс), чтобы иметь возможность выполнять мою сериализацию. Я мог бы написать пару заявлений о случаях, чтобы выполнить работу, но это означало бы, что мне приходится обновлять несколько функций каждый раз, когда я хотел добавлять класс.

Чтобы обойти эту проблему, я впервые определил последовательность из кортежи содержащий отображение:

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

Имена верхних чехлов определяются, которые удерживают INT, а имена нижних регистра - это классы, которые я определил где -то еще.

Затем я могу использовать эту последовательность в сочетании с некоторыми из Повысить препроцессоры Чтобы создать всевозможные коды для меня. Например, чтобы получить форвардную объявление о классах, я могу просто сделать это:

#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

Чтобы выполнить время выполнения для составления картирования времени, я генерирую серию операторов, подобных этим:

#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

Весь код включает в себя немного больше, чем этот, но это все равно должно дать вам представление о том, как генерировать код, используя препроцессоры Boost. В своем примере я могу быстро и легко добавить поддержку сериализации для класса, просто обновив свою последовательность.

Обратите внимание, что использование препроцессора Boost не производит очень читаемый код, поэтому я стараюсь держать макрос, используемый для каждого макроса как можно проще. Также я не удивлюсь, если у кого -то есть более элегантное решение этой проблемы. Это именно то, что я придумал для личного проекта, где я не возражаю против дополнительной сложности.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top