首页 文章

boost序列化std :: unique_ptr支持

提问于
浏览
8

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

编译器(btw gcc4.7与-std = c 11标志)抛出错误

/usr/include/boost/serialization/access.hpp:118:9: error: ‘class std::unique_ptr’ has no member named ‘serialize’

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

4 回答

  • 8

    不,没有开箱即用的适应性 . 您需要自己提供一个非侵入式适配器 . 请参阅tutorial here以了解如何执行此操作 .

  • 3

    我不确定如何解释this list,但似乎在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;
    }
    
  • 8

    正如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;
    }
    
  • 2

    最新版本的boost序列化为所有std智能指针类型提供支持 .

相关问题