
Hi Robert. On Mon, Apr 4, 2011 at 2:44 AM, Robert Ramey <ramey@rrsd.com> wrote:
Hi Takatoshi. Nice hear from you. Havn't heard from you in a while.
Thanks for reply. BTW, I'll attend the boost-con 2011, I'm looking forward to seeing you again :)
... example and expanation in previous post.
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); // My approach // ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B);
If I pass it B instead of A, the following exception would be occurred. "unregistered void cast struct C<-struct A"
Hmmm ... Are sure you don't mean to say "If I pass it A instead of B"
Oh.. I exactly want to say "If I pass it A instead of B". Thanks for your mind-reading :)
One of he side effects of BOOST_SERIALIZATION_BASE_OBJECT_NVP(A) (orB) is to invoke void_cast_register<base class, derived class> ...
My understanding is so.
I would think that you could skip B in this case. But one would have to more carefully investigate how this macro is implemented.
Note that if B is implemented as just another macro ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); so things can be done the normal way, I would hope that a release build would collapse the code to be equivalent to your method of skipping B.
Does "collapse" mean to be omitted by optimizer? (Good meaning?)
It's also possible the the macro implementation could be refined and/or enhanced to permit the skipping of B if it doesn't do so already.
Note that the tests/examples include one case where the void cast register is called directly - thereby eliminating the call to the macro. This short circuits the whole process and would be the most efficient. This is why I believe that the macro could be modified to directly pass A instead of B
I checked test_void_cast.cpp. It's very interesting. I can remove the dependency on the serialization library from class A, B and C completely. I can add polymorphic serialization capability later (non intrusively). Amazing! #include <boost/serialization/serialization.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/export.hpp> #include <fstream> // ------------------------------------------------------------------------- struct A { explicit A(int vala_):vala(vala_) {} // pure virtual // to bypass serialize() requirement // If it is non pure, serialize() and default constructor are required. virtual ~A() = 0 {} int vala; }; struct B : public A { B(int vala_, int valb_):A(vala_), valb(valb_) {} int valb; }; struct C : public B { C(int vala_, int valb_, int valc_):B(vala_, valb_), valc(valc_) {} int valc; }; // ------------------------------------------------------------------------- namespace boost { namespace serialization { template<class Archive> void serialize(Archive& /*ar*/, C&, unsigned int const /*version*/) {} template<class Archive> void save_construct_data(Archive& ar, C const* p, unsigned int const /*version*/) { ar << boost::serialization::make_nvp("vala", p->vala); ar << boost::serialization::make_nvp("valb", p->valb); ar << boost::serialization::make_nvp("valc", p->valc); } template<class Archive> void load_construct_data(Archive& ar, C* p, unsigned int const /*version*/) { int a, b, c; ar >> boost::serialization::make_nvp("vala", a); ar >> boost::serialization::make_nvp("valb", b); ar >> boost::serialization::make_nvp("valc", c); ::new(p) C(a, b, c); } }} BOOST_CLASS_EXPORT(C) int main() { { std::ofstream ofs("test.xml"); C c(1, 2, 3); A* a(&c); boost::archive::xml_oarchive oa(ofs); oa << boost::serialization::make_nvp("a", a); } { std::ifstream ifs("test.xml"); boost::archive::xml_iarchive ia(ifs); A* a; ia >> boost::serialization::make_nvp("a", a); C* c = dynamic_cast<C*>(a); assert(c); assert(c->vala == 1); assert(c->valb == 2); assert(c->valc == 3); delete a; } // void_cast_register direct call boost::serialization::void_cast_register<C, A>( static_cast<C *>(NULL), static_cast<A *>(NULL) ); } P.S. I'm in the business trip now. I can't access my primary email account now. This is my second email address. Regards, Takatoshi