【发布时间】:2018-01-13 10:12:08
【问题描述】:
我正在研究一种“数据变量”框架。在这里,使用宏 BOOST_FUSION_DEFINE_ASSOC_STRUCT 将结构体定义和改编为 Boost.Fusion 序列。
简要背景:
要定义两个适应的结构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 在 .../define_assoc_struct.hpp 的第 40-50 行定义。在.../define_struct.hpp(尤其是第 413 行上的宏BOOST_FUSION_DEFINE_STRUCT_IMPL)中似乎可以找到构建这些宏的大部分魔法。该文件还利用了很多 Boost.PP。
编译器: Microsoft Visual Studio 2015 Update 3(GCC、Clang 目前不是选项)。
提升: 1.64.0.
【问题讨论】:
-
我只需生成代码或修改现有的 BOOST_FUSION_DEFINE_STRUCT 宏(复制它并让它发出您渴望的代码)
-
@sehe 这是个好主意。实际上正是我的想法。我的问题是使用
__VA_ARGS__,这样我就可以获得与 Boost.Fusion 宏相同的可变参数行为。也许我可以复制 Boost.Fusion 实现,不确定。我会稍微更新一下问题。
标签: c++ c++11 boost c-preprocessor boost-preprocessor