4

I'm really not sure how do i go/start for boost deserialization. Below is sample code for which want to know how do the boost deserialization code would be.

#include <boost/serialization/access.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/smart_ptr/make_shared.hpp>

namespace mydata
{
    struct MyInfo 
    {
        std::string info = "extra info";

        MyInfo(std::string info) : info(std::move(info)) {}

        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive &ar, const unsigned int /*version*/)
            {
                ar & info;
            }
    };

    struct MyData
    {
        std::string name;
        std::string type;
        boost::shared_ptr<MyInfo> myref;

        private:
        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive &ar, const unsigned int /*version*/)
            {
                ar & name;
                ar & type;
                ar & myref;
            }
    };
}



 int main()
    {

        using namespace mydata;
        MyData data { "this is a name", "this is a type", boost::make_shared<MyInfo>("this is info") };

        boost::archive::text_oarchive oa(std::cout);
        oa << data;
    }

There is also link similar to deserialization but was not clear on Boost deserialize a derived class to base class pointer .

I really don't know much.. it would really helpful..if i get link on boost deserialization also if there exist.

Community
  • 1
  • 1
sia
  • 1,872
  • 1
  • 23
  • 54

1 Answers1

6

You were almost there:

int main()
{
    using namespace mydata;
    MyData data { "this is a name", "this is a type", boost::make_shared<MyInfo>("this is info") };

    std::ostringstream oss;
    {
        boost::archive::text_oarchive oa(oss);
        oa << data;
    }

    std::istringstream iss(oss.str());
    {
        boost::archive::text_iarchive ia(iss);
        ia >> data;
    }
}

In fact, you could use std::stringstream for both the input and output, but for purity I showed the symmetric approaches (which does redundant copying).

You'll need

#include <sstream>
#include <boost/archive/text_iarchive.hpp>

and for deserialization your classes need to be defaultconstructible:

MyInfo(std::string info = "") : info(std::move(info)) {}

(unrelated warning: do not use std::string info = {} here because that triggers a compiler bug in MSVC)

Here's a fully working sample that shows that the deserialized object has the same data: Live On Coliru

#include <boost/serialization/access.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/smart_ptr/make_shared.hpp>

#include <sstream>
#include <boost/archive/text_iarchive.hpp>

namespace mydata
{
    struct MyInfo 
    {
        std::string info = "extra info";

        MyInfo(std::string info = "") : info(std::move(info)) {}

        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive &ar, const unsigned int /*version*/)
            {
                ar & info;
            }
    };

    struct MyData
    {
        std::string name;
        std::string type;
        boost::shared_ptr<MyInfo> myref;

        private:
        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive &ar, const unsigned int /*version*/)
            {
                ar & name;
                ar & type;
                ar & myref;
            }
    };
}

int main()
{
    using namespace mydata;

    std::ostringstream oss;
    {
        MyData data { "this is a name", "this is a type", boost::make_shared<MyInfo>("this is info") };

        boost::archive::text_oarchive oa(oss);
        oa << data;
    }

    MyData cloned;
    std::istringstream iss(oss.str());
    {
        boost::archive::text_iarchive ia(iss);
        ia >> cloned;
    }

    // check equality
    {
        std::ostringstream oss2;

        boost::archive::text_oarchive oa(oss2);
        oa << cloned;

        std::cout << oss.str()  << "\n";
        std::cout << oss2.str() << "\n";
    }
}

Output:

22 serialization::archive 10 0 0 14 this is a name 14 this is a type 0 1 2 1 0
0 12 this is info

22 serialization::archive 10 0 0 14 this is a name 14 this is a type 0 1 2 1 0
0 12 this is info
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks Sehe. So i do not need add any deserialize template for MyData struct. Let me try it the way shown in above code – sia Apr 11 '14 at 21:57
  • I added a fully working sample [live on Coliru](http://coliru.stacked-crooked.com/a/f07cc68f6a457a7d). `serialize` combines (de)serialization (which is why it's not a `const` member). Some types will require splitting the deserialization functions, see e.g. [here (arrays with allocation)](http://stackoverflow.com/a/20599449/85371) and [here (rational numbers)](http://stackoverflow.com/questions/22563255/how-to-serialize-boostrational/22564432#22564432) – sehe Apr 11 '14 at 22:02
  • is below code.. does deserialization MyData cloned; std::istringstream iss(oss.str()); { boost::archive::text_iarchive ia(iss); ia >> cloned; } – sia Apr 11 '14 at 22:34