我遇到了使用std :: vector of std :: unique_ptr' s的boost序列化的问题。 unique_ptr的类型无关紧要,在下面的示例中,使用了整数:
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <fstream>
namespace boost {
namespace serialization {
template <class Archive>
void serialize(Archive& ar, std::vector<unique_ptr<int>>& g, const unsigned int version) {
ar& g;
}
} // namespace serialization
} // namespace boost
int main(int argc, char** argv){
std::vector<std::unique_ptr<int>> v_out;
const std::string archName = "test_arch.xml";
v_out.push_back(make_unique<int>(1));
v_out.push_back(make_unique<int>(2));
v_out.push_back(make_unique<int>(3));
// Serialize vector
std::ofstream ofs(archName);
{
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(v_out);
}
ofs.close();
std::vector<std::unique_ptr<int>> v_in;
// Deserialize vector
std::ifstream ifs(archName);
{
boost::archive::xml_iarchive ia(ifs);
// next line fails to build
ia >> BOOST_SERIALIZATION_NVP(v_in);
}
ifs.close();
remove(archName.c_str());
}
根据注释的规定,当尝试将输入存档中的deserialize运算符用于std::vector<std::unique_ptr<...>>
时,程序无法编译。
抛出的错误是:
/usr/include/c++/5/ext/new_allocator.h:120: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
在GCC&#39> new_allocator.h 第120行引发。
116: #if __cplusplus >= 201103L
117: template<typename _Up, typename... _Args>
118: void
119: construct(_Up* __p, _Args&&... __args)
120: { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
121:
122: template<typename _Up>
123: void
124: destroy(_Up* __p) { __p->~_Up(); }
125: #else
126: ...
上面的示例在Windows和OS X上按预期构建和运行 - 这只能在linux上编译 该应用程序链接到以下库(使用CMake):
target_link_libraries(app ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SERIALIZATION_LIBRARY})
链接命令在所有平台上都相同。 我正在使用boost 1.67并使用GCC 5.4.0在Ubuntu 16.04上进行编译
以下CMakeLists.txt用于项目:
set (CMAKE_CXX_STANDARD 14)
add_executable(test main.cpp)
set(Boost_NO_SYSTEM_PATHS OFF)
set(BOOST_INCLUDEDIR "$ENV{BOOST_ROOT}")
find_package(Boost COMPONENTS serialization REQUIRED)
target_link_libraries(test ${Boost_SERIALIZATION_LIBRARY})
答案 0 :(得分:1)
您无需为矢量提供序列化。事实上,这样做是因为你没有在序列化函数中提供NVP包装而破坏了它。
删除它。
接下来,Serialization不期望(唯一指针)原始类型。出于这个原因,在这个例子中,无论你使用int
还是一些简单的结构X
, 都很重要。
旁注:您需要在(反)序列化上使用一致的XML名称。您有
v_out
与v_in
无效。
修正样本:
<强> Live On Coliru 强>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <fstream>
#include <memory>
struct X {
X(int = 0) {}
template <typename Ar> void serialize(Ar&, unsigned) {}
};
int main() {
std::vector<std::unique_ptr<X> > v_out;
const std::string archName = "test_arch.xml";
v_out.push_back(std::make_unique<X>(1));
v_out.push_back(std::make_unique<X>(2));
v_out.push_back(std::make_unique<X>(3));
// Serialize vector
{
std::ofstream ofs(archName);
boost::archive::xml_oarchive oa(ofs);
oa << boost::serialization::make_nvp("root", v_out);
}
// Deserialize vector
{
std::ifstream ifs(archName);
boost::archive::xml_iarchive ia(ifs);
// next line fails to build
std::vector<std::unique_ptr<X> > v_in;
ia >> boost::serialization::make_nvp("root", v_in);
}
remove(archName.c_str());
}
要进行非侵入式序列化:
struct X {
X(int i = 0) : _i(i) {}
int _i;
};
namespace boost { namespace serialization {
template <class Archive>
void serialize(Archive& ar, X& x, unsigned) {
ar& BOOST_SERIALIZATION_NVP(x._i);
}
} }
<强> Live On Coliru 强>