3

我想为

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

通过查看 mpl 序列,但我需要能够识别对象并将其检索回来,我不知道如何获取它成员的名称,我必须知道它吗?

代码应该看起来像

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

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

我想通过用户只定义一个与对象布局对应的mpl序列来生成上面的代码,是否可行,你能给我一些提示吗?

我的目标是:

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

4

3 回答 3

10

Consider a boost::fusion, and use the macro BOOST_FUSION_ADAPT_STRUCT() to promote your structure to a fusion sequence (random access), e.g. once you've defined the above structure, you can do something like

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

Now that it's been promoted, you can simply use a for_each to iterate over the members, something like:

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));
}

To use, it should be as simple as:

Object foo; // instance to serialize
serialize(<archive>, foo);
于 2011-05-16T22:36:47.270 回答
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>>formember将它们合并为 a member_vec,以及一个operator>>formember_vec合并为更大的member_vec. 由于您只使用类型,编译器可以优化掉任何实际的函数调用

函数可以使用隐式模板参数,因此它可以使序列化器使用更少的代码来定义:

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

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

于 2011-05-16T20:17:01.383 回答
0

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

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

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

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

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

于 2011-06-03T05:21:40.557 回答