提升序列化标准::unique_ptr 支持

boost serialization std::unique_ptr support

本文关键字:ptr 支持 unique 序列化 标准 升序      更新时间:2023-10-16

boost 序列化库是否支持 std::unique_ptr 的序列化?我尝试编译下面的代码,但是如果我包含boost::archive::text_oarchive oa(ofs); oa <<g;线

编译器(顺便说一句,带有 -std=C++11 标志的 GCC4.7)抛出错误

/

usr/include/boost/serialization/access.hpp:118:9:错误:"类 std::unique_ptr"没有名为"序列化"的成员

#include <iostream>
#include <memory>
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
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;
    {// compiler error, fine if commented out
        boost::archive::text_oarchive oa(ofs); oa << g;
    }
  return 0;
}

我不确定如何解释此列表,但似乎在 1.48 之后的某个时候添加了对此的支持。我正在使用 1.58,它包含在内。只

#include <boost/serialization/unique_ptr.hpp>

然后它将按如下方式工作:

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

正如 pmr 提到的,我设法提出了以下解决方案,乍一看,一切正常。希望有人能发现它有用:

#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;
}
最新版本的

boost 序列化提供了对所有 std 智能指针类型的支持。

Boost 现在支持智能指针,您可以 #include 头文件进行Unique_Ptr。

 #include <boost/serialization/unique_ptr.hpp>

不,没有开箱即用的适应。您需要自己提供非侵入式适配器。请参阅此处的教程以了解如何执行此操作。