[serialization, boost::function] stateful function objects

Hi there, I have a class that is being serialized in regular intervals. It contains a vector<shared_ptr<somefunctionObject> > . As the somefunctionObject objects can maintain state, I want to be able to serialize them along with the surrounding class. This works fine with the current design. I would find it much more pleasing to replace the above vector e.g. with a vector<boost::function<void(someType)> >. From the program logic this would have the same effect, but would be more elegant. I can not see, though, how serialization would work in this case. As far as I know it is not possible to retrieve the object back from boost::function. And it is also not possible to specify more than one interface to boost::function, e.g. in order to support two operator() with different signatures like this: "boost::function<void(someFunctionObkject), someFunctionObject(void)> f;" If that was possible, I could just give the function object a "clone" function and write my own (de-)serialization code. Any ideas ? Thanks and Best Regards, Ruediger Berlich

Hmmm ... i have used non-intrusive serialization on a function object without problems. So I don't see a problem here so I'm clearly missing something. Robert Ramey Ruediger Berlich wrote:
Hi there,
I have a class that is being serialized in regular intervals. It contains a vector<shared_ptr<somefunctionObject> > . As the somefunctionObject objects can maintain state, I want to be able to serialize them along with the surrounding class. This works fine with the current design.
I would find it much more pleasing to replace the above vector e.g. with a vector<boost::function<void(someType)> >. From the program logic this would have the same effect, but would be more elegant.
I can not see, though, how serialization would work in this case. As far as I know it is not possible to retrieve the object back from boost::function. And it is also not possible to specify more than one interface to boost::function, e.g. in order to support two operator() with different signatures like this:
"boost::function<void(someFunctionObkject), someFunctionObject(void)> f;"
If that was possible, I could just give the function object a "clone" function and write my own (de-)serialization code.
Any ideas ?
Thanks and Best Regards, Ruediger Berlich

On Fri, 07 Dec 2007 16:52:26 -0800, Robert Ramey wrote:
i have used non-intrusive serialization on a function object without problems.
So I don't see a problem here so I'm clearly missing something.
Hey, can you post this please? I'm clearly missing something because I did some wholly backward thing. -- Sohail Somani http://uint32t.blogspot.com

I'l have to go dig it up. I'll post it if you make a demo out of it and prepare documentation to add to the "Case Studies" section of the manual. Robert Ramey Sohail Somani wrote:
On Fri, 07 Dec 2007 16:52:26 -0800, Robert Ramey wrote:
i have used non-intrusive serialization on a function object without problems.
So I don't see a problem here so I'm clearly missing something.
Hey, can you post this please? I'm clearly missing something because I did some wholly backward thing.

On Fri, 07 Dec 2007 20:16:41 -0800, Robert Ramey wrote:
I'l have to go dig it up.
I'll post it if you make a demo out of it and prepare documentation to add to the "Case Studies" section of the manual.
Robert Ramey
Let see how pretty it is first :-) -- Sohail Somani http://uint32t.blogspot.com

On Fri, 07 Dec 2007 20:16:41 -0800, Robert Ramey wrote:
I'l have to go dig it up.
I'll post it if you make a demo out of it and prepare documentation to add to the "Case Studies" section of the manual.
Robert Ramey
Sohail Somani wrote:
On Fri, 07 Dec 2007 16:52:26 -0800, Robert Ramey wrote:
i have used non-intrusive serialization on a function object without problems.
So I don't see a problem here so I'm clearly missing something.
Hey, can you post this please? I'm clearly missing something because I did some wholly backward thing.
I just realized I read your post wrong (by reading the other posts.) I thought you said you added non-intrusive serialization on a boost::function object without problems. If this *is* indeed the case, please do post it. -- Sohail Somani http://uint32t.blogspot.com

Hi there,
Hmmm ...
i have used non-intrusive serialization on a function object without problems.
So I don't see a problem here so I'm clearly missing something.
Robert Ramey
See below for a working example. The code that doesn't work is commented out at the end. If boost::function would provide an access method for the objects stored in it, writing the serialization code would be no big deal, I would assume. As it is, however, I think I'll have to stick to the vector<shared_ptr<functionObject> > . Best, Ruediger Berlich /********************************************************************/ #include <iostream> #include <sstream> #include <boost/function.hpp> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <boost/random.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/utility.hpp> using namespace std; using namespace boost; class functionObject{ /////////////////////////////////////////////////////////////// friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version){ using boost::serialization::make_nvp; ar & make_nvp("innerState_", innerState_); } /////////////////////////////////////////////////////////////// public: functionObject(void){ innerState_=0; } functionObject(int is){ innerState_=is; } void operator()(void){ cout << "Inner state is " << innerState_ << endl; } private: int innerState_; }; main(){ vector<shared_ptr<functionObject> > A; for(int i=1; i<4; ++i){ shared_ptr<functionObject> p(new functionObject(i)); A.push_back(p); } // Serialization works ostringstream oss; { boost::archive::xml_oarchive oa(oss); oa << boost::serialization::make_nvp("functionObjectContainer", A); } cout << oss.str() << endl; // Now the same with boost::function() vector<function<void(void)> > B; for(int i=1; i<4; ++i) B.push_back(functionObject(i)); vector<function<void(void)> >::iterator it; // Calls functionObject::operator(), works for(it=B.begin(); it!=B.end(); ++it) (*it)(); // *** Does not work: *** // ostringstream oss2; // { // boost::archive::xml_oarchive oa(oss2); // oa << boost::serialization::make_nvp("functionContainer", B); // } // cout << oss2.str() << endl; // // Compilation fails with error message: // error: ‘struct boost::function<void ()(), std::allocator<void> >’ // has no member named ‘serialize’ }

Ruediger Berlich wrote:
Hi there,
Hmmm ...
i have used non-intrusive serialization on a function object without problems.
So I don't see a problem here so I'm clearly missing something.
Robert Ramey
See below for a working example. The code that doesn't work is commented out at the end. If boost::function would provide an access method for the objects stored in it, writing the serialization code would be no big deal, I would assume. As it is, however, I think I'll have to stick to the vector<shared_ptr<functionObject> > .
If you know the type of function object stored in the boost::function object, you can extract a pointer to the object via the "target" method. See: http://www.boost.org/doc/html/boost/function.html#id697895-bb - Doug

On 8 Dec 2007, at 07:55, Ruediger Berlich wrote:
Hi there,
I have a class that is being serialized in regular intervals. It contains a vector<shared_ptr<somefunctionObject> > . As the somefunctionObject objects can maintain state, I want to be able to serialize them along with the surrounding class. This works fine with the current design.
I would find it much more pleasing to replace the above vector e.g. with a vector<boost::function<void(someType)> >. From the program logic this would have the same effect, but would be more elegant.
I can not see, though, how serialization would work in this case. As far as I know it is not possible to retrieve the object back from boost::function. And it is also not possible to specify more than one interface to boost::function, e.g. in order to support two operator() with different signatures like this:
"boost::function<void(someFunctionObkject), someFunctionObject(void)> f;"
If that was possible, I could just give the function object a "clone" function and write my own (de-)serialization code.
Indeed there is too much type erasure happening here. What is it that you don't like with vector<shared_ptr<somefunctionObject> >? Matthias

Indeed there is too much type erasure happening here. What is it that you don't like with vector<shared_ptr<somefunctionObject> >?
Hi Matthias, vector<shared_ptr<somefunctionObject> > works fine from a technical point of view, but forces users of this class to provide the call backs in a particular format. That is where boost::function can help, as users can give me call back functions either as function pointers or as function objects, and they can use boost::bind to make some of their own functions fit the requirements of the callback. However, as serialization is a vital requirement of my application, I guess I have to stick with the original vector<shared_ptr> solution. Best Regards, Ruediger Berlich
participants (5)
-
Douglas Gregor
-
Matthias Troyer
-
Robert Ramey
-
Ruediger Berlich
-
Sohail Somani