[serialization] how to serialize boost::function

Hello, Is it possible to serialize the following class: struct foo { void f1(int a) {} void f2(const std::string& s) {} void init() { using boost::bind; functors_.push_back(bind(&foo::f1, this, 1)); functors_.push_back(bind(&foo::f2, this, "test")); } std::vector<boost::function<void(void)> > functors_; }; That is, I'd like save the functors, in order to run them later, when the object is loaded from the archive. A straightforward attempt fails: struct foo { //...... friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(functors_); } }; 1>d:\dev\servision\projects\windows\thirdparty\boost\boost\serialization\access.hpp(109) : error C2039: 'serialize' : is not a member of 'boost::function<Signature>'

It looks like the problem has no solution in general. If you know what are all possible target types for your function objects, and if all target types define op==, then you can pull it off by basically searching for all possibilities when you write and recording an ID of some sort. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

It looks like the problem has no solution in general. If you know what are all possible target types for your function objects, and if all target types define op==, then you can pull it off by basically searching for all possibilities when you write and recording an ID of some sort.
In my case these are various functions of the object itself (just like in my example): when it's loaded, it should invoke them in some order with some params. So, if I understand correctly, since I can't bind()-and-serialize all the stuff together, the only solution is to make separate function object for every function, initialize it with the params, and serialise it.

Emil Dotchevski wrote:
It looks like the problem has no solution in general. If you know what are all possible target types for your function objects, and if all target types define op==, then you can pull it off by basically searching for all possibilities when you write and recording an ID of some sort.
That's pretty much equivalent to what boost::variant does. Robert Ramey
Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

An interesting topic which I've yet to find time to address. You're trying to serialize a pointer to a function. This is not implemented within the library. I would suggest a couple of ideas. Make each f1, f2... a function object. Make a boost::variant<f1, f2, ...> and serialize that. The library already supports serialization of variants. Another idea would be to dervive all function objects from a common base struct fbase { virtual void operator()(int a) = 0; // makes fbase polymorphic } and serialize through a base class pointer struct foo { fbase * f; std::vector<fbase *> functors_; void init(){ functors_.pushback(& f1...); }; Robert Ramey Igor R wrote:
Hello,
Is it possible to serialize the following class:
struct foo { void f1(int a) {} void f2(const std::string& s) {}
void init() { using boost::bind; functors_.push_back(bind(&foo::f1, this, 1)); functors_.push_back(bind(&foo::f2, this, "test")); }
std::vector<boost::function<void(void)> > functors_; };
That is, I'd like save the functors, in order to run them later, when the object is loaded from the archive.
A straightforward attempt fails:
struct foo { //...... friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(functors_); } };
1>d:\dev\servision\projects\windows\thirdparty\boost\boost\serialization\access.hpp(109)
error C2039: 'serialize' : is not a member of 'boost::function<Signature>'

"Igor R" <boost.lists@gmail.com> wrote in message news:cfe0a3cf0909150846l4290d47yd03b8ea7f33e0b53@mail.gmail.com...
Ok, thank you. So the way to go is to make "manual" function objects...
We have a system that serializes boost::function - they are used as factory objects that are sent through sockets (via asio). We only support serializing boost::function with functors, but the mechanism works well. Fortunately, boost::function has the target<> method that can be used to get access to the original type. As touched upon by an earlier post, we have to look up the types from some kind of registry that associates the boost::function (the signature) with the type (the functor) that can be assigned into it. This means we have to register each association, but this is similar to registering polymorphic class types (i.e. archive.register_type<>). It may be possible to generalize the mechanism, but it would probably require a new export macro that can associate the types, e.g. a BOOST_FUNCTION_EXPORT(signature, func_name, type, type_name) to go along with BOOST_CLASS_EXPORT.

Why don't you just derived all the functors from a common base and serialize a base class pointer? You wouldn't have to do anything special since polymorphic pointers are already addressed. Robert Ramey Chard wrote:
"Igor R" <boost.lists@gmail.com> wrote in message news:cfe0a3cf0909150846l4290d47yd03b8ea7f33e0b53@mail.gmail.com...
Ok, thank you. So the way to go is to make "manual" function objects...
We have a system that serializes boost::function - they are used as factory objects that are sent through sockets (via asio).
We only support serializing boost::function with functors, but the mechanism works well. Fortunately, boost::function has the target<> method that can be used to get access to the original type.
As touched upon by an earlier post, we have to look up the types from some kind of registry that associates the boost::function (the signature) with the type (the functor) that can be assigned into it. This means we have to register each association, but this is similar to registering polymorphic class types (i.e. archive.register_type<>).
It may be possible to generalize the mechanism, but it would probably require a new export macro that can associate the types, e.g. a BOOST_FUNCTION_EXPORT(signature, func_name, type, type_name) to go along with BOOST_CLASS_EXPORT.

"Robert Ramey" <ramey@rrsd.com> wrote in message news:h8osbi$ndv$1@ger.gmane.org...
Why don't you just derived all the functors from a common base and serialize a base class pointer? You wouldn't have to do anything special since polymorphic pointers are already addressed.
This was just a constraint of design; a hierarchy could not be imposed on the function objects. Further, they could not be serialized themselves because their construction relied on data only available at the other socket side, hence the factory approach. Yes there are other approaches, but it panned out the boost::function way and has been quite flexible.
participants (4)
-
Chard
-
Emil Dotchevski
-
Igor R
-
Robert Ramey