3

我想寻找一个MPL序列生成Boost MPL为对象序列化生成代码?

class Object 
{ 
    string a; 
    int b; 
    long c; 
    char d; 
}; 

串行/解串码,但我需要能够识别对象并获取回为好,我想不通我怎么会得到它的成员的名字,我必须知道它

代码看起来应该像

void SerializeObject(ostream os) 
{ 
    serialize(object.a, os); 
    serialize(object.b, os); 

    //serialize(object.member, os); 
} 

我想用户只定义相应的对象布局的MPL序列生成上面的代码,是可行的,你可以给我一些提示?

我的目的是:

用户对上述对象定义mpl::vector<String, int, long, char>和我的metaprogram可以生成编码需要的。

+0

我不认为你可以得到你的成员的名字没有一些严重的黑客攻击。考虑如果你有两个整数会发生什么。 boost :: mpl如何知道哪个int是哪个? – 2011-05-16 19:48:45

+0

@Boaz,我不在乎,只要我以同样的顺序得到两个int,就可以通过它们了。 – 2011-05-16 19:51:53

回答

2

有没有办法推断模板中的成员名称。你需要明确指定的一切,就像这样:

template<typename ObjT, typename MemberT, MemberT ObjT::*Ptr> 
struct member{}; 

mpl::vector 
< 
    member<Object, string, &Object::a>, 
    member<Object, int, &Object::b>, 
    member<Object, long, &Object::c>, 
    member<Object, char, &Object::d> 
>; 

另一种选择是创建功能,帮助生成member,定义为operator>>member它们合并成一个member_vecoperator>>member_vec是并入更大的member_vec。既然你只使用类型,编译器可以优化掉任何实际的函数调用

函数可以使用隐式模板参数,因此它可以使串行拿少一点代码来定义:

auto serializer = 
     mem(&Object::a) >> 
     mem(&Object::b) >> 
     mem(&Object::c) >> 
     mem(&Object::d); 

我我自己制作了序列化器,使用了这两种技术。第二个是我最满意的。

10

考虑boost::fusion,并使用宏BOOST_FUSION_ADAPT_STRUCT()来将您的结构推广到融合序列(随机存取),例如,一旦你定义上面的结构,你可以这样做

BOOST_FUSION_ADAPT_STRUCT(
    Object, 
    (std::string, a) 
    (int, b) 
    (long, c) 
    (char, d) 
) 

现在,它的被提拔,你可以简单地用一个for_each遍历成员,是这样的:

template<typename archive> 
struct serializer { 
    serializer(archive& ar):ar(ar) {} 

    template<typename T> 
    void operator()(const T& o) const { 
     ar & o; // assuming binary for example... 
    } 
    archive& ar; 
}; 

template<typename archive, typename sequence> 
void serialize(archive& ar, sequence const& v) { 
    boost::fusion::for_each(v, serializer<archive>(ar)); 
} 

要它应该如此简单:

Object foo; // instance to serialize 
serialize(<archive>, foo); 
0

您可以使用mpl::string来表示成员名称。在我的应用程序中,我会做一些代码生成,它会发出类似下面的内容。

typedef mpl::string < 'n', 'a', 'm', 'e' > name; 

您可以使用mpl::c_str <name>::value来获取字符串表示形式。即“名称”。

我存储一个这样的成员名称序列,成员指针的另一个序列,将它们压缩在一起,然后使用boost :: fusion查询算法之一来查找给定成员名称的成员指针。

如果您有兴趣,我会发布代码。目前我无法访问它,因为它位于我的家用PC中。