无法使C ++ Boost Pointer序列化工作 [英] Can't get C++ Boost Pointer Serialization to work

查看:131
本文介绍了无法使C ++ Boost Pointer序列化工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题与重复列出的问题不同:增强c ++序列化字符* 我没有使用shared_ptr,并且可以完全访问我的类的内部.

This question is not the same as the one listed as duplicate: Boost c++ serializing a char * I am not using shared_ptr, and I have full access to the internals of my classes.

我能找到的最接近的响应是在 Store中通过搜索编译器错误找到的指向文件的自定义对象的指针向量.

The closest response I could find was in Store a vector of pointers to custom objects to file which I found by searching for the compiler error.

但是,给出的答案不清楚,至少对我来说不是.它指向了boost文档,表明我在这里列出的简单代码应该可以使用.在对所有通过指针对对象进行序列化的内务处理进行分类之后,boost文档会这样说.

However, the answer given there was not clear, at least not to me. It points back to the boost docs, which indicate that the simple code I have listed here should work. After cataloguing all the housekeeping that goes into serializing objects by pointer, the boost docs say this.

此序列化库解决了以上所有注意事项.

This serialization library addresses all of the above considerations.

如果我必须一次写一个char []字符,或者如果我必须取消引用容器中的所有指针对象并将其分解为它们的组成POD部分,则先将它们的大小以字节为单位依次写入流中使用boost进行序列化,那么使用boost似乎没有多大意义.那是大部分工作.创建文本输出流并将字节喷射到其中很简单.

If I must write a char[] one character at a time, or if I must dereference all pointer objects in a container and break them down to their constituent POD parts, writing their sizes in bytes to the stream first, in order to serialize with boost, then there doesn't seem to be much point in using boost. That's the lion's share of the work. Creating a text output stream and squirting bytes into it is trivial.

我并不是在上面说我可能对文档有阅读理解的问题,但是从我对所读内容的理解来看,下面的代码片段应该可以工作.但是,此代码发出以下编译器错误.所以,我必须省略一些东西,但是我看不到它,所以这就是我寻求帮助的原因.

I'm not above saying that I may have a reading comprehension issue with the docs, but from my understanding of what I've read, the code snippet below should work. However, this code emits the following compiler error. So, I must be omitting something, but I just can't see it, so that's why I'm asking for help.

在下面的代码片段中简单指出故障点怎么样?或者,甚至更好地提供一个有效的代码段?

How about simply pointing out the failure point in the code snippet below? Or, even better, providing a snippet that does work?

/usr/include/boost/serialization/access.hpp:118:9: error: ‘class boost::ptr_vector<std::basic_string<char> >’ has no member named ‘serialize’
         t.serialize(ar, file_version);
         ^

#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

class A {
public:
        A(){}

        char c;
        char *name;

        friend boost::serialization::access;
        template<class Archive>

        void serialize(Archive& ar, unsigned version) 
        {
                ar &  name;
        }
};

main()
{
        A a;
        a.name = (char *)"this is a test";

        std::ofstream ofs("table.txt");
        boost::archive::text_oarchive os(ofs);
        os << a;
}

我可以序列化int,char甚至STL类型,但是我不能使用指针序列化任何东西.例如,我可以序列化 std :: vector< std :: string> ,但是如果我尝试序列化 std :: vector< std :: string *> ,我会得到编译器错误.

I can serialize int, char, even STL types, but I cannot serialize anything with a pointer. For example, I can serialize std::vector<std::string>, but if I attempt to serialize std::vector<std::string *>, I will get the compiler error.

推荐答案

如果我必须一次写一个char []字符,或者如果我必须取消引用容器中的所有指针对象并将其分解为它们的组成POD部分,则先将它们的大小以字节为单位依次写入流中要使用boost进行序列化,那么使用boost似乎没有多大意义.

If I must write a char[] one character at a time, or if I must dereference all pointer objects in a container and break them down to their constituent POD parts, writing their sizes in bytes to the stream first, in order to serialize with boost, then there doesn't seem to be much point in using boost.

是的.但是您正在尝试序列化一个指针.指向 char 的指针应序列化为什么?当然, T * 应该序列化动态分配的 T ,不是吗?因此,除非 name nullptr ?

Yes. But you're trying to serialize a pointer. What should a pointer to char be serialized as? Surely T* should serialize a dynamically allocated T, no? So you would expect to serialize a single char unless name were nullptr?

还是您希望获得对每个序列化字符的完整对象跟踪?

Or do you expect to get full object tracking for each character serialized?

这里的重点是您选择了指向原始类型的原始指针.指针缺少必要的信息.因此,您有责任添加信息.如果您发现乏味,则可以自由使用C ++类型.

The whole point here is that you chose a raw pointer to a primitive type. The pointer lacks the necessary information. Hence, the onus is on you to add the information. If you find that tedious, you're free to use C++ types instead.

请注意,顺便说一句,这在C ++ 03及更高版本中均不合法:

Note, by the way, that this is not legal in C++03 and up anyways:

a.name = (char *)"this is a test";

char const(&)[15] 静态转换为 char * 会丢弃const限定符.无论如何,您的编译器都应拒绝此代码.

A static cast from char const(&)[15] to char * would drop a const qualification. Your compiler should reject this code anyways.

这是我的看法(使用 std :: string ):

Here's my take on it (use std::string):

#include <boost/serialization/string.hpp>
#include <boost/archive/text_oarchive.hpp>

class A {
  public:
    std::string name;
    template <class Archive> void serialize(Archive &ar, unsigned) {
        ar & name;
    }
};

int main() {
    A a { "this is a test" };
    boost::archive::text_oarchive os(std::cout);
    os << a;
}

偶然地,链接的重复问题的标题与您在此处尝试执行的操作完全匹配:

Incidentally, the linked duplicate question's title exactly matches what you're trying to do here: Boost c++ serializing a char * and the accepted answer displays exactly the same solution.

如果您真的坚持,那么您当然可以不费吹灰之力地处理一些C风格的代码:

If you really insist, you can of course go mud-wrestle some C-style code for no glory:

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <cstring>
#include <cstdlib>

class A {
  public:
    A(char const* sz = nullptr) : name(sz? strdup(sz) : nullptr) {}
    A(A const&) = delete;
    A& operator=(A const&) = delete;

    ~A() { free(name); }

  private:
    char* name;

    template <class Archive> void save(Archive &ar, unsigned) const {
        bool have_name = name;
        ar & have_name;

        if (have_name)
        {
            size_t len = strlen(name);
            ar & len;
            ar & boost::serialization::make_binary_object(name, len);
        }
    }

    template <class Archive> void load(Archive &ar, unsigned) {
        bool have_name = name;
        ar & have_name;

        if (!have_name)
        {
            free(name);
            name = nullptr;
        } else
        {
            size_t len = 0;
            ar & len;

            name = static_cast<char*>(realloc(name, len));
            ar & boost::serialization::make_binary_object(name, len);
        }
    }

    friend class boost::serialization::access;
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};


int main() {
    A a { "this is a test" };
    boost::archive::text_oarchive os(std::cout);
    os << a;
}

但是,所有这些使您获得的代码量,残缺的价值语义,完全放弃的关注分离,潜在的许多bug(是您想到的 name == null strlen(name)== 0 ?目前,我的实现会使用未指定的(实现定义的)行为.我将它作为练习供读者使用,以便在此处提出密封处理),甚至...甚至都不可读的字符串输出.

But all this gains you is 6x as much code, crippled value semantics, completely abandoned separation of concerns, a lot of bug potential (did you think of the difference between having name==null and strlen(name)==0? Currently my implementation employs unspecified (implementation-defined) behaviour. I'll leave it as an exercise to you, the reader, to come up with airtight handling here) and... not even readable string output.

是的,当然, make_array 会给您 14116104105115321051153297 32116101115116 ,而不是 dGhpcyBpcyBhIHRlc3Q = ,但是这在存储方面效率低下,而且仍然难以辨认.

Yes, of course make_array would give you 14 116 104 105 115 32 105 115 32 97 32 116 101 115 116 instead of dGhpcyBpcyBhIHRlc3Q=, but that's horrifically storage inefficient and still not human readable.

这篇关于无法使C ++ Boost Pointer序列化工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆