Я работаю над своего рода фреймворком "данные-переменные". Здесь структуры определены и адаптированы как последовательности Boost.Fusion с использованием макроса BOOST_FUSION_DEFINE_ASSOC_STRUCT
.
Краткий контекст:
Чтобы определить две адаптированные структуры foo
и bar
, я использую:
#define VAR(VARNAME) vardefs::VARNAME
#define VAR_PARENTHESES(VARNAME) (vardefs)(VARNAME)
// ========================================================
#ifndef VARNAME_
#define VARNAME_ foo // <- Variable name
namespace VAR(VARNAME_)::keys{
struct foo1;
struct foo2;
struct foo3;
}
namespace VAR(VARNAME_) { struct index; }
BOOST_FUSION_DEFINE_ASSOC_STRUCT(
VAR_PARENTHESES(VARNAME_), type,
(char, foo1, VAR(VARNAME_)::keys::foo1)
(int, foo2, VAR(VARNAME_)::keys::foo2)
(float, foo3, VAR(VARNAME_)::keys::foo3)
)
#endif
#undef VARNAME_
// --------------------------------------------------------
// ========================================================
#ifndef VARNAME_
#define VARNAME_ bar // <- Variable name
namespace VAR(VARNAME_)::keys{
struct bar1;
struct bar2;
}
namespace VAR(VARNAME_) { struct index; }
BOOST_FUSION_DEFINE_ASSOC_STRUCT(
VAR_PARENTHESES(VARNAME_), type,
(double, bar1, VAR(VARNAME_)::keys::bar1)
(float, bar2, VAR(VARNAME_)::keys::bar2)
)
#endif
#undef VARNAME_
// --------------------------------------------------------
Теперь можно создавать экземпляры foo
и bar
, используя:
VAR(foo)::type fooI;
VAR(bar)::type barI;
Ассоциативные ключи можно использовать так:
auto a = boost::fusion::at_key<VAR(foo)::keys::foo3>(fooI).
auto b = boost::fusion::at_key<VAR(bar)::keys::bar2>(barI).
Этот подход может быть полезен в будущем.
Наконец, есть теги для самих структур:
VAR(bar)::index
VAR(foo)::index
Я могу использовать более позднее как типовые ключи в других последовательностях Boost.Fusion, например. boost::fusion::map
.
Вопрос:
Обратите внимание, что для каждой из двух структур, и поскольку я определяю ассоциативную последовательность, я должен использовать имена полей структуры (foo1
, bar2
, ...) по три раза каждое.
Вместо этого я хотел бы определить две приведенные выше структуры следующим образом:
// ========================================================
DEFINE_DATAVAR_STRUCT(
foo,
(char, foo1)
(int, foo2)
(float, foo3)
)
// --------------------------------------------------------
// ========================================================
DEFINE_DATAVAR_STRUCT(
bar,
(double, bar1)
(float, bar2)
)
// --------------------------------------------------------
Мне нужно только определить вариативный макрос DEFINE_DATAVAR_STRUCT
. Вот для чего мне нужна помощь. Проблема для меня в том, чтобы повторно использовать вариативные аргументы, чтобы они могли появляться не только в сгенерированном коде. Каким-то образом Boost.Fusion делает это без проблем (полагаясь на Boost.PP).
Мое собственное исследование:
Я просмотрел библиотеку Boost.PP, но у меня не очень хороший прогресс. Поскольку библиотека Boost.Fusion уже делает это, должен быть способ достичь той же вариативной функциональности, подобной макросу BOOST_FUSION_DEFINE_ASSOC_STRUCT
.
Макрос Boost.Fusion BOOST_FUSION_DEFINE_ASSOC_STRUCT
определен в строках 40-50 в ... / define_assoc_struct.hpp. Кажется, большая часть волшебства для создания этих макросов находится в ... / define_struct.hpp (особенно макрос BOOST_FUSION_DEFINE_STRUCT_IMPL
в строке 413). Этот файл также использует множество преимуществ Boost.PP.
Компилятор: Microsoft Visual Studio 2015 с обновлением 3 (GCC, Clang сейчас недоступны).
Boost: 1.64.0.
__VA_ARGS__
, так что я могу получить такое же вариативное поведение, что и макрос Boost.Fusion. Возможно, я могу просто скопировать реализацию Boost.Fusion, не уверен. Я немного обновлю вопрос. - person Ole Thomsen Buus   schedule 05.08.2017