Boost MPL 生成对象序列化代码?

发布于 2024-11-07 06:41:01 字数 540 浏览 1 评论 0原文

我想

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,我的元程序可以生成所需的编码。

I want to generate serialization/deserialization code for

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

by looking at a mpl sequence, but I need to be able to identify object and retrieve it back as well, I can't figure out how would I get the names of it members, do I have to know it?

code should look like

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

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

I want to generate above code by user only defining a mpl sequence corresponding the object layout, is it doable, can you give me some hints?

my aim is:

User defines mpl::vector<String, int, long, char> for above object and my metaprogram can generate the coded needed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北音执念 2024-11-14 06:41:01

考虑一个 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);

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);
肩上的翅膀 2024-11-14 06:41:01

无法推断模板中的成员名称。您需要明确指定所有内容,如下所示:

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,为 member 定义一个 operator>> code> 将它们合并为一个 member_vec,以及将 member_vec 合并为一个更大的 member_vecoperator>> >。由于您只使用类型,因此编译器可以优化任何实际的函数调用。

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

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

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

There are no ways to infer member names in templates. You'll need to specify everything explicitly, like this:

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

Another option is to create functions to help generate member, define an operator>> for member that merges them into a member_vec, and an operator>> for member_vec that merges into a larger member_vec. Since you're only using the type, the compiler can optimize away any actual function calls

Functions can use implicit template arguments, so it can make serializers take a bit less code to define:

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

I've made serializers myself, using both techniques. The second one is what I'm most happy with.

满地尘埃落定 2024-11-14 06:41:01

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

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

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

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

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

You can use mpl::string to represent member names. In my app, I do a little bit of code generation that emits something like the following.

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

You can use the mpl::c_str < name >::value to get the string representation. i.e. "name".

I store a sequence of such member names, another sequence for member pointers, zip them together and then use one of the boost::fusion query algorithms to find the member pointer for a given member name.

I'll post code if you are interested. Currently I don't have access to it since it is in my home PC.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文