我尝试使用boost MPL和fusion实现类似Java的注释系统。
为什么需要: 我需要注释成员var以获得一些特殊的运行时功能。 我注册在编译时尝试它们到我的基地clase:
class foo
{
INIT()
$REGISTER("test1")
int test1 = 5;
$REGISTER("b")
char* b = "rndmText";
....
}
我的目标是指针和$ REGISTER(& a," a")等文本的组合,但这是未来的目标...
Base类处理所有必要的东西。 寄存器宏创建融合矢量:
#define INIT() \
typedef boost::fusion::vector0<> BOOST_PP_CAT(registered, BOOST_PP_SUB(__COUNTER__,2)); \
boost::fusion::vector0<> BOOST_PP_CAT(list,BOOST_PP_SUB(__COUNTER__,2));
#define EXPORT(arg) \
typedef boost::fusion::result_of::push_back< BOOST_PP_CAT(registered, BOOST_PP_SUB(__COUNTER__,4)), const char*>::type BOOST_PP_CAT(registered, __COUNTER__); \
BOOST_PP_CAT(registered, BOOST_PP_DEC(__COUNTER__)) BOOST_PP_CAT(list, BOOST_PP_SUB(__COUNTER__,1)) = boost::fusion::make_list(BOOST_PP_CAT(list,BOOST_PP_SUB(__COUNTER__,7)), arg);
这会扩展(在我的情况下):
typedef boost::fusion::vector0<> registered18;
boost::fusion::vector0<> list19;;
typedef boost::fusion::result_of::push_back< registered18, const char*>::type registered23;
registered23 list24 = boost::fusion::make_list(list19, "test1");;
int test1 = 5;
typedef boost::fusion::result_of::push_back< registered23, const char*>::type registered28;
registered28 list29 = boost::fusion::make_list(list24, "b");;
char* b = "rndmText";;
以下是问题所在: boost :: fusion :: make_list(...,&#34; test1&#34;)创建编译器错误,我不知道如何解决它。这是错误:
boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>>::joint_view(const boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>> &)' : cannot convert argument 1 from 'boost::fusion::list<T,const char (&)[6],boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_,boost::fusion::void_>' to 'const boost::fusion::joint_view<Sequence,const boost::fusion::single_view<const char *>> &'
有人可以帮助我或者有更好的主意吗?
多米尼克
答案 0 :(得分:3)
这对编译错误没有帮助(对不起),但评论时间太长了。
有人可以帮助/或者有更好的主意吗?
我认为你在滥用宏。请考虑使用此客户端代码:
class foo: public registered<foo> {
int test1 = 5;
char* b = "rndmText";
public:
foo();
virtual ~foo() = default;
};
foo::foo() : registered<foo>{ "foo" } {
register(&i, "i"); // part of the interface of the base class
register(&b, "b");
}
说明:
基类现在提供相同的功能。 CRTP实现意味着如果您有两个(或更多)继承自registered
的类,它们不在同一个类层次结构中(因为元数据的加入不应该在不相关的具体类之间强加类关系) )。
registered<T>
的实现可以在内部使用boost::fusion
(如果需要,可以使用其他内容),并且可以隐藏一个方便别名(例如using data_sequence = boost::fusion::vector0<>
)背后的三米长的声明。 / p>
INIT()
部分将自然地构建registered<T>
实例(和公共接口)。
此实现完全避免了宏,并允许您以更优雅的方式向客户端代码公开元数据,可能只需从registered<T>
的API导入。