提升序列化字符串*

时间:2014-11-15 12:36:58

标签: c++ serialization boost

我尝试在我的类中创建一个名为location的序列化函数,并在序列化后发送它。我无法弄清楚为什么我会收到错误,但也许是因为我试图序列化字符串*。

这是一个最小的例子

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

struct WithPointers {
    WithPointers(const char* of = nullptr, const char* n = nullptr) {
        if (n) name = new std::string(n);
    }

    WithPointers(WithPointers const&) = delete;
    WithPointers& operator=(WithPointers const&) = delete;

    ~WithPointers() { 
        delete name; 
    }

    std::string* name = nullptr;

    template <class Archive>
    void serialize(Archive &ar, unsigned int) {
        ar & name;
    }
};

struct WithoutPointers {

    WithoutPointers(const char* of = nullptr, const char* n = nullptr) {
        if (n) name = n;
    }

    std::string name;

    template <class Archive>
    void serialize(Archive &ar, unsigned int) {
        ar & name;
    }
};

#include <iostream>
#include <sstream>

int main()
{
    std::string serialized; 

    typedef WithoutPointers Location; // DOESN'T COMPILE
    //typedef WithPointers Location;  // COMPILES

    {
        Location l1("da location", "da name");
        std::ostringstream oss;
        boost::archive::text_oarchive oa(oss);

        oa << l1;
        serialized = oss.str();
    }

    std::cout << "serialized: '" << serialized << "'\n";
}    

如果我们使用WithoutPointers

,它就有效

1 个答案:

答案 0 :(得分:1)

公平地说,我没有看到为什么这不起作用的原因。在我看来,这是一种任意的限制,甚至可能是一个错误。

相比之下,这是一个简单包装std::string

的版本
struct XString {
    std::string s;

    template <class Archive>
    void serialize(Archive &ar, unsigned int) {
        ar & s;
    }
};

有趣的是,使用它一切都按预期工作:

struct WithPointers {
    WithPointers(const char* n = nullptr) {
        if (n) name = new XString ({ n });
    }

    WithPointers(WithPointers const&) = delete;
    WithPointers& operator=(WithPointers const&) = delete;

    ~WithPointers() { 
        delete name; 
    }

    XString* name = nullptr;

    template <class Archive>
    void serialize(Archive &ar, unsigned int) {
        ar & name;
    }
};

查看 Live On Coliru

打印:

serialized: '22 serialization::archive 11 0 0 1 1 0
0 7 da name'
Deserialized as 'da name'

摘要

我仍然建议不要使用原始std::string*。除此之外,你应该在Boost邮件列表中提到这个问题

完整列表

供参考:

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

struct XString {
    std::string s;

    template <class Archive>
    void serialize(Archive &ar, unsigned int) {
        ar & s;
    }
};

struct WithPointers {
    WithPointers(const char* n = nullptr) {
        if (n) name = new XString ({ n });
    }

    WithPointers(WithPointers const&) = delete;
    WithPointers& operator=(WithPointers const&) = delete;

    ~WithPointers() { 
        delete name; 
    }

    XString* name = nullptr;

    template <class Archive>
    void serialize(Archive &ar, unsigned int) {
        ar & name;
    }
};

#include <iostream>
#include <sstream>

int main()
{
    std::string serialized; 

    typedef WithPointers Location;

    {
        Location l1("da name");
        std::ostringstream oss;
        boost::archive::text_oarchive oa(oss);

        oa << l1;
        serialized = oss.str();
    }

    std::cout << "serialized: '" << serialized << "'\n";

    {
        Location l2;
        std::istringstream iss(serialized);
        boost::archive::text_iarchive ia(iss);

        ia >> l2;
        std::cout << "Deserialized as '" << l2.name->s << "'\n";
    }
}