1

我尝试使用 boost MPL 和融合来实现类 Java 注释系统。

为什么需要它:我需要注释成员 var 以具有一些特殊的运行时功能。我在编译时将它们注册到我的基类,如下所示:

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(..., "test1") 创建一个编译器错误,我不知道如何解决它。这是错误:

 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 *>> &'

有人可以帮助我或有更好的主意吗?

多米尼克

4

1 回答 1

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<>)。

INIT()部分将在registered<T>实例(和公共接口)的构建中自然而然地进行。

此实现完全避免了宏,并允许您以更优雅的方式将元数据公开给客户端代码,可能只需从registered<T>.

于 2014-10-02T17:10:24.877 回答