boost serialization std::unique_ptr support

ε祈祈猫儿з 提交于 2019-12-03 12:25:16
pmr

No, there is no out of the box adaption. You will need to provide a non-intrusive adapter yourself. See the tutorial here to get an idea how to do that.

I'm not sure how to interpret this list, but it seems like support for this was added sometime after 1.48. I am using 1.58 and it is included. Just

#include <boost/serialization/unique_ptr.hpp>

and then it will work as follows:

#include <memory>

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

#include <fstream>

class Point
{
public:
    Point() { }

    float x = 1.;
    float y = 2.;
    float z = 3.;

private:
    friend class boost::serialization::access;

    template<class TArchive>
    void serialize(TArchive & archive, const unsigned int version)
    {
        archive & x;
        archive & y;
        archive & z;
    }
};

void ValidUniquePointer()
{
    std::unique_ptr<Point> p(new Point());

    std::ofstream outputStream("test.txt");
    boost::archive::text_oarchive outputArchive(outputStream);
    outputArchive << p;
    outputStream.close();

    // read from a text archive
    std::unique_ptr<Point> pointRead;
    std::ifstream inputStream("test.txt");
    boost::archive::text_iarchive inputArchive(inputStream);
    inputArchive >> pointRead;

    std::cout << pointRead->x << " " << pointRead->y << " " << pointRead->z << std::endl;

}

void NullUniquePointer()
{
    std::unique_ptr<Point> p;

    std::ofstream outputStream("test.txt");
    boost::archive::text_oarchive outputArchive(outputStream);
    outputArchive << p;
    outputStream.close();

    // read from a text archive
    std::unique_ptr<Point> pointRead;
    std::ifstream inputStream("test.txt");
    boost::archive::text_iarchive inputArchive(inputStream);
    inputArchive >> pointRead;

    if(pointRead != nullptr) {
        std::cout << pointRead->x << " " << pointRead->y << " " << pointRead->z << std::endl;
    }
    else {
        std::cout << "Pointer is null!" << std::endl;
    }

}

int main()
{
    ValidUniquePointer();
    NullUniquePointer();
    return 0;
}
dodol

as mentioned by pmr, I managed to come up the following solution, and at the first glance, everything works. In hope that someone could find it useful:

#include <iostream>
#include <memory>
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
namespace boost { 
namespace serialization {

template<class Archive, class T>
inline void save(
    Archive & ar,
    const std::unique_ptr< T > &t,
    const unsigned int /*file_version*/
){
    // only the raw pointer has to be saved
    const T * const base_pointer = t.get();
    ar & BOOST_SERIALIZATION_NVP(base_pointer);
}
template<class Archive, class T>
inline void load(
    Archive & ar,
    std::unique_ptr< T > &t,
    const unsigned int /*file_version*/
){
    T *base_pointer;
    ar & BOOST_SERIALIZATION_NVP(base_pointer);
    t.reset(base_pointer);
}
template<class Archive, class T>
inline void serialize(
    Archive & ar,
    std::unique_ptr< T > &t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}
} // namespace serialization
} // namespace boost

class MyDegrees
{
public:
  void setDeg(int d){deg = d;}
  int getDeg()const {return deg;}
private:
  friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    { ar & deg; }
  int deg;
};
class gps_position
{
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    { ar & degrees;  }
    std::unique_ptr<MyDegrees> degrees;
public:
    gps_position(): degrees(std::unique_ptr<MyDegrees>(new MyDegrees)){};
    void setDeg(int d){degrees->setDeg(d);}
    int getDeg() const {return degrees->getDeg();}
};
int main()
{
    std::ofstream ofs("filename");
    gps_position g;
    g.setDeg(45);
    std::cout<<g.getDeg()<<std::endl;
    { boost::archive::text_oarchive oa(ofs); oa << g; }
    gps_position newg;
    {
        std::ifstream ifs("filename");
        boost::archive::text_iarchive ia(ifs);
        ia >> newg;
        std::cout<<newg.getDeg()<<std::endl;
    }
  return 0;
}

recent versions of boost serialization provide support for all std smart pointer types.

Boost now supports smart pointers you can you #include header file for Unique_Ptr.

 #include <boost/serialization/unique_ptr.hpp>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!