我正在尝试使用boost::serialization库来序列化一个包含std::unique_ptr成员的类(下面代码中的类A)。
环境:
操作系统: Windows 10 1909
IDE: Microsoft Visual Studio Community 2019版本16.4.4
库: boost-serialization 1.72.0 (随vcpkg工具安装)
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <fstream>
#include <iostream>
#include <memory>
using namespace std;
using namespace boost;
class A
{
public:
A()
{
}
A(int input_size, int input_value) // Constructor
{
this->data = std::make_unique<int[]>(input_size);
this->size = input_size;
for (int loop_number = 0; loop_number < size; loop_number++) {
data[loop_number] = input_value;
}
}
std::unique_ptr<int[]> get_data()
{
// deep copy
auto return_data = std::make_unique<int[]>(size);
for (int loop_number = 0; loop_number < size; loop_number++) {
return_data[loop_number] = data[loop_number];
}
return return_data;
}
int get_size()
{
return this->size;
}
~A()
{
}
private:
std::unique_ptr<int[]> data;
int size;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar& data;
ar& size;
}
};
int main()
{
// create and open a character archive for output
std::ofstream ofs("filename");
// create class instance
const A a_object(10, 5);
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << a_object;
// archive and stream closed when destructors are called
}
// ... some time later restore the class instance to its orginal state
A load_from_file;
{
// create and open an archive for input
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia >> load_from_file;
// archive and stream closed when destructors are called
}
return 0;
}编译器抛出C2440错误,错误消息为'initializing': cannot convert from 'int *' to 'const T (*const )'。它是指%includePath%\boost\serialization\unique_ptr.hpp
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
// the ref count is rebuilt automatically on load
const T * const tx = t.get();
ar << BOOST_SERIALIZATION_NVP(tx);
}似乎std::unique_ptr在boost-serialization库(1.72.0版)中仍然无法成功序列化?此外,有没有什么解决方案可以序列化带有std::unique_ptr成员的类?
发布于 2020-02-24 22:38:15
基于"serialize“模板函数中用于保存/加载数据成员的std::unique_ptr doesn't stored size、ar& data;不能被序列化的事实,因为该行中的数据计数是未知的。
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar& data; // <== the count of data is unknown
ar& size;
}为了访问所有有效数据,需要执行智能指针" data“的迭代过程(如下面的代码所示)。
for (int i = 0; i < size; ++i)
ar& data[i];因此,保存部分如下所示。
template<class Archive>
void save(Archive& ar, const unsigned int version) const
{
ar& size;
for (int i = 0; i < size; ++i)
ar& data[i];
}对于加载部分,重要的是在加载数据之前分配智能指针的空间,以避免访问冲突错误
template<class Archive>
void load(Archive& ar, const unsigned int version)
{
ar& size;
data = std::make_unique<int[]>(size); // <== allocate space of smart pointer first
for (int i = 0; i < size; ++i)
ar& data[i];
}注意:宏BOOST_SERIALIZATION_SPLIT_MEMBER()需要放入,因为保存/加载函数被拆分了。
最后,类A中的序列化部分可以像下面的代码一样完成。
friend class boost::serialization::access;
template<class Archive>
void save(Archive& ar, const unsigned int version) const
{
ar& size;
for (int i = 0; i < size; ++i)
ar& data[i];
}
template<class Archive>
void load(Archive& ar, const unsigned int version)
{
ar& size;
data = std::make_unique<int[]>(size);
for (int i = 0; i < size; ++i)
ar& data[i];
}
BOOST_SERIALIZATION_SPLIT_MEMBER()发布于 2020-02-22 00:04:26
根据您使用的Boost版本,您可能需要实现自己的非侵入式适配器,如下所示:
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有关完整的示例,请参阅this。
https://stackoverflow.com/questions/60341575
复制相似问题