C ++ Variadic Macros в Boost.Fusion? - PullRequest
3 голосов
/ 18 мая 2011

Итак, согласно этому ответу , C ++ не поддерживает вариационные макросы, а стандарт C ++ нигде не упоминает вариационные макросы.Я знаю, что в C99 были введены макросы с переменным числом __VA_ARGS__, а некоторые компиляторы C ++ (например, GCC) даже предоставляют расширения, позволяющие это делать в C ++, но факт остается фактом, что макросы с переменным значением просто не являются частью стандартного C ++.

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

Вот пример того, как это используется (взято из документа Boost):

namespace demo
{
    struct employee
    {
        std::string name;
        int age;
    };
}

// demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_STRUCT(
    demo::employee,
    (std::string, name)
    (int, age))

Теперькак этот код возможен без макроса variadic?Макрос BOOST_FUSION_ADAPT_STRUCT, по-видимому, принимает произвольное количество аргументов, поскольку, предположительно, он может работать с любым произвольным определяемым пользователем классом или структурой.

Я знаю, что Boost славится изгибанием C ++ интересными способами, но этокажется невозможным без поддержки компилятора.Так какого рода волшебство Boost.Fusion делает для этого?

PS: Да, я знаю, что Boost с открытым исходным кодом.Первым делом я посмотрел на исходный код.Кажется, он использует библиотеку Boost Preprocessor для объединения макросов.Но я не понимаю, как это может работать для любого произвольного числа аргументов, и исходный код представляет собой очень плотную коллекцию кода препроцессора, который очень трудно понять.

1 Ответ

2 голосов
/ 18 мая 2011
BOOST_FUSION_ADAPT_STRUCT(
    demo::employee,
    (std::string, name)
    (int, age))

Это один макрос, который принимает два аргумента: Аргумент 1: demo :: employee Аргумент 2: (std :: string, name) (int, age)

Аргумент 2 объединяется сстрока для формирования другого вызова макроса, который также принимает 2 параметра:

BOOST_FUSION_SOME_INTERNAL_MACRO(std::string, name)
BOOST_FUSION_SOME_INTERNAL_MACRO(int, age)
...