C++ std unique\u ptr的stl集合的boost序列化

C++ std unique\u ptr的stl集合的boost序列化,c++,boost,c++11,boost-serialization,C++,Boost,C++11,Boost Serialization,我希望能够序列化std::unique\u ptrs的stl容器。能做到吗? 顺便说一句,使用单个std::unique\u ptr,一切都很好。 下面是我正在编写的代码,gcc给出了以下错误: 使用已删除函数“std::unique\u ptr::unique\u ptr(const std::unique_ptr&)[带_Tp=MyDegrees;_Dp= std::default\u delete;std::unique\u ptr= std::unique_ptr]' 我怎样才能使代码

我希望能够序列化std::unique\u ptrs的stl容器。能做到吗? 顺便说一句,使用单个std::unique\u ptr,一切都很好。 下面是我正在编写的代码,gcc给出了以下错误:

使用已删除函数“std::unique\u ptr::unique\u ptr(const
std::unique_ptr&)[带_Tp=MyDegrees;_Dp=
std::default\u delete;std::unique\u ptr=
std::unique_ptr]'
我怎样才能使代码正常工作

#include <iostream>
#include <memory>
#include <fstream>
#include <map>
#include <vector>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_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 tx = t.get();
    //ar << tx;
    ar << boost::serialization::make_nvp("px", tx);
}
template<class Archive, class T>
inline void load(
    Archive & ar,
    std::unique_ptr< T > &t,
    const unsigned int file_version
) {
    T *pTarget;
    //ar >> pTarget;
    ar >> boost::serialization::make_nvp("px", pTarget);

#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
    t.release();
    t = std::unique_ptr< T >(pTarget);
#else
    t.reset(pTarget);
#endif
}
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; }
    {
        ar & boost::serialization::make_nvp("DEGS", 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;  }
    {
        ar & boost::serialization::make_nvp("DEGS2", degrees);
        ar & boost::serialization::make_nvp("DEGMAP", deg_map);
    }
    std::unique_ptr<MyDegrees> degrees;
    std::vector<std::unique_ptr<MyDegrees> > deg_map;
public:
    gps_position(): degrees(std::unique_ptr<MyDegrees>(new MyDegrees)) {};
    void setDeg(int d) {
        degrees->setDeg(d);
    }
    int getDeg() const {
        return degrees->getDeg();
    }
};

int TestBasicSerialize(int, char *[])
{
    int numErr = 0;
    double a;
    std::ofstream ofs("filename");
    gps_position g;
    g.setDeg(45);
    std::cout<<g.getDeg()<<std::endl;
    {
        boost::archive::text_oarchive oa(ofs);
        oa << g;
    }
    //{ boost ::archive::xml_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 numErr;

}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
名称空间提升{
命名空间序列化{
模板
内联作废保存(
存档和ar,
const std::unique_ptr&T,
常量无符号整数文件\u版本
) {
//只需保存原始指针
常数T*常数tx=T.get();
//ar>pTarget;
ar>>boost::serialization::make_nvp(“px”,pTarget);
#if BOOST_变通方法(BOOST_DINKUMWARE_STDLIB,==1)
t、 释放();
t=std::unique_ptr(pTarget);
#否则
t、 重置(pTarget);
#恩迪夫
}
模板
内联空序列化(
存档和ar,
标准:唯一性,
常量无符号整数文件\u版本
) {
boost::serialization::split_free(ar、t、file_版本);
}
}//命名空间序列化
}//名称空间提升
我的学位类别
{
公众:
void setDeg(int d){
deg=d;
}
int getDeg()常量{
返回度;
}
私人:
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
//{ar°;}
{
ar和boost::序列化::制造nvp(“DEGS”,deg);
}
内度;
};
类gps_位置
{
私人:
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
//{ar°rees;}
{
ar和boost::序列化::生成nvp(“DEGS2”,度);
ar和boost::序列化::生成nvp(“DEGMAP”,DEGMAP);
}
std::唯一的ptr度;
std::矢量deg_图;
公众:
gps_position():度(std::unique_ptr(new MyDegrees)){};
void setDeg(int d){
度->设置度(d);
}
int getDeg()常量{
返回度->获取度();
}
};
int-TestBasicSerialize(int,char*[])
{
整数=0;
双a;
std::ofs流(“文件名”);
gps_位置g;
g、 setDeg(45);

std::cout问题在于容器反序列化程序试图复制构造唯一的\u ptr。 为了演示,请考虑以下代码,这些代码产生相同的错误:

std::vector< std::unique_ptr<int> > vec;
std::unique_ptr<int> p;
vec.push_back(p); // does not compile!

最省力的解决方案是使用可复制的智能指针, 例如,
boost::shared\u ptr
,它随 它在
boost/serialization/shared_ptr.hpp
中预定义的序列化实现


下一个解决方案是在类内手动序列化向量:

//NOTE: this replaces void serialize(...) in gps_position
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
    ar & BOOST_SERIALIZATION_NVP(degrees);
    size_t size = deg_map.size();
    ar & BOOST_SERIALIZATION_NVP(size);
    for( auto it=deg_map.begin(), end=deg_map.end(); it!=end; ++it )
       ar & boost::serialization::make_nvp("item",*it);
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
    ar & BOOST_SERIALIZATION_NVP(degrees);
    size_t size = 0;
    ar & BOOST_SERIALIZATION_NVP(size);
    deg_map.clear();
    deg_map.reserve(size);
    while( size-- >= 0 ) {
        std::unique_ptr<MyDegrees> p;
        ar & boost::serialization::make_nvp("item",p);
        deg_map.push_back(std::move(p));
    }
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
最后但并非最不重要的是,您应该使用:

oa << BOOST_SERIALIZATION_NVP(g);
// and
ia >> BOOST_SERIALIZATION_NVP(newg);
oa>BOOST\u SERIALIZATION\u NVP(newg);

在TestBasicSerialize()中使用xml存档时。

这是否意味着我必须为每个容器实现序列化程序?此外,应该特别小心,不要包括原始的boost容器序列化程序,这在我看来有点麻烦hassle@dodol对于包含唯一容器的每个容器。或者采取简单的方法,将共享容器与默认容器一起使用boost提供的序列化程序。
namespace boost { namespace serialization {
//NOTE: do not include boost/serialization/vector.hpp
template<class Archive, class T, class Allocator>
inline void save(
    Archive & ar,
    const std::vector<T, Allocator> &t,
    const unsigned int
){
    collection_size_type count (t.size());
    ar << BOOST_SERIALIZATION_NVP(count);
    for(auto it=t.begin(), end=t.end(); it!=end; ++it)
        ar << boost::serialization::make_nvp("item", (*it));
}

template<class Archive, class T, class Allocator>
inline void load(
    Archive & ar,
    std::vector<T, Allocator> &t,
    const unsigned int
){
    collection_size_type count;
    ar >> BOOST_SERIALIZATION_NVP(count);
    t.clear();
    t.reserve(count);
    while( count-- > 0 ) {
        T i;
        ar >> boost::serialization::make_nvp("item", i);
        t.push_back(std::move(i)); // use std::move
    }
}

template<class Archive, class T, class Allocator>
inline void serialize(
    Archive & ar,
    std::vector<T, Allocator> & t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}
} } // namespace boost::serialization
oa << BOOST_SERIALIZATION_NVP(g);
// and
ia >> BOOST_SERIALIZATION_NVP(newg);