Проблема с сериализацией function_wrapper
Есть такой код.
#include <iostream>
#include <memory>
#include <fstream>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/assume_abstract.hpp>
using namespace std;
struct impl_base {
virtual void call() = 0;
virtual ~impl_base() {}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version){}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(impl_base)
template<typename F>
struct impl_type : impl_base {
F f;
impl_type(F&& f_) : f{std::move(f_)} {}
void call() { f(); }
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<impl_base>(*this) & f;
}
};
class function_wrapper {
std::unique_ptr<impl_base> impl;
public:
template<typename F>
function_wrapper(F&& f) : impl(new impl_type<F>(std::move(f))) {}
void operator()() { impl->call(); }
function_wrapper() = default;
function_wrapper(function_wrapper&& other) : impl(std::move(other.impl)) {}
function_wrapper& operator=(function_wrapper&& other)
{
impl = std::move(other.impl);
return *this;
}
function_wrapper(const function_wrapper&) = delete;
function_wrapper(function_wrapper&) = delete;
function_wrapper& operator=(const function_wrapper&) = delete;
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & impl;
}
};
BOOST_CLASS_EXPORT(function_wrapper)
void hel() { cout << "WTF" << endl;}
void serialize_task()
{
function_wrapper task(std::bind(&hel));
task();
std::ofstream ofs("task.dat");
boost::archive::text_oarchive oar(ofs);
oar << task;
ofs.close();
// Загрузка объекта из файла
std::ifstream ifs("task.dat");
boost::archive::text_iarchive iar(ifs);
function_wrapper loaded_task;
iar >> loaded_task;
ifs.close();
// Проверка результатов сериализации
loaded_task();
}
int main() {
serialize_task();
return 0;
}
Есть базовый класс impl_base
, для которого применяю BOOST_SERIALIZATION_ASSUME_ABSTRACT(impl_base)
, как показано в офиц.документации serialization.
И дальше я пытаюсь тестить при помощиvoid serialize_task()
. (bind
нужен, он на своем месте).
Вопрос в целом - что же надо зарегистрировать, чтобы ошибка
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unregistered class - derived class not registered or exported`
перестала высовываться???
P.S. Boost
последней версии, собираю при помощи g++ -o a a.cpp -lboost_serialization
.
Как подсказал @user7860670 - у меня все-таки нет регистрации impl_type
. Тогда я вынес его и impl_base
из function_wrapper
и добавил к коду регистрацию через экспорт BOOST_CLASS_EXPORT(impl_type<function<void()>>)
для объекта типа function<void()>
, так как у меня в примере должна вызваться функция void hell(){..}
:
struct impl_base {
virtual void call() = 0;
virtual ~impl_base() {}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version){}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(impl_base)
template<typename F>
struct impl_type : impl_base {
F f;
impl_type(F&& f_) : f{std::move(f_)} {}
void call() { f(); }
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<impl_base>(*this) & f;
}
};
BOOST_CLASS_EXPORT(impl_type<function<void()>>)
class function_wrapper {....
Но это не помогло, так как начала появляться другая ошибка:
error: ‘class std::function<void()>’ has no member named ‘serialize’
116 | t.serialize(ar, file_version);
Что скорее всего свидетельствует о том, что объект ‘class std::function<void()>’ нельзя сериализовать.
Мой вопрос - это так или нет? Если мои мысли верны, то вопрос можно закрыть, если нет, то прошу совета, что исправить в коде.