[serialization] Different behaviors between archive and its polymorphic variant
Hi,
I'm trying to make a custom archive class that works either with the
template flavor or via the polymorphic_archive. It compiles but produces
a different behavior and I can't find why.
Basically I did a trivial oarchive class that overloads (via
save_override) how are treated NVP. When used with the template version
it works, whereas with the polymorphic version it doesn't.
The code is attached. There is a preprocessor switch to choose the
template or polymorphic version (-DPOLY).
$ g++ poly.cc -lboost_serialization && ./a.out
On 08/07/2010 03:54 PM, Maxime van Noppen wrote:
I looked at various archive implementations but couldn't find any code that I could relate to this problem.
Little bump. I still get the same behavior with Boost 1.44 so it seems I'm doing something wrong but I really can't find what. :-/ Any idea? Thanks, -- Maxime
make a small example which illustrates the problem and we'll take a look a it. It's not clear to me that one should necessarily expect that the output of an archive class should be identical to it's polymorphic variant. Robert Ramey Maxime van Noppen wrote:
On 08/07/2010 03:54 PM, Maxime van Noppen wrote:
I looked at various archive implementations but couldn't find any code that I could relate to this problem.
Little bump. I still get the same behavior with Boost 1.44 so it seems I'm doing something wrong but I really can't find what. :-/ Any idea?
Thanks,
On 08/18/2010 04:04 PM, Robert Ramey wrote:
make a small example which illustrates the problem and we'll take a look a it.
In the first post I attached such an example.
It's not clear to me that one should necessarily expect that the output of an archive class should be identical to it's polymorphic variant.
So code that uses the polymorphic variant might not work with code that doesn't even though they use the same archive class though trough different methods ? It seems a bit strange to me. However, the problem isn't there actually. What happens in the example is that when used through the template variant, save_override is correctly used, though with the polymorphic one it isn't. -- Maxime
Maxime van Noppen wrote:
On 08/18/2010 04:04 PM, Robert Ramey wrote:
make a small example which illustrates the problem and we'll take a look a it.
In the first post I attached such an example.
I went back and looked at your example. You're on the wrong track here.
First, classes to be serialized should be not dependent in anyway upon
any archive class. So use:
class unit
{
public:
unit() : id_(0) { }
unit(int id) : id_(id) { }
template <typename Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(id_);
}
private:
int id_;
};
note that "polymorphism" is not implemented via virtual functions in the
archive class itself so your archive should be dependent on whether or note
you're using the polymorphic_archive template.
class test_oarchive : public
boost::archive::detail::common_oarchive
polymorphic_test_oarchive;
// required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( test_oarchive ) or something like this. Now you should have test_oarchive and polymorphic_test_oarchive Robert Ramey
On 08/18/2010 06:42 PM, Robert Ramey wrote:
I went back and looked at your example. You're on the wrong track here.
Thank you very much!
First, classes to be serialized should be not dependent in anyway upon any archive class. So use:
Ouch. The reason why I wanted polymorphic archives was to be able to have a non-template serialize() method so that it may be implemented and compiled once for all in the .cpp file.
Test the above to verify that it works according to your taste.
I still have a different behavior when serializing through polymorphic_test_oarchive.
Now use a "templated typedef" to generate the polymorphic version:
#include
#include #include typedef boost::archive::detail::polymorphic_oarchive_route< test_oarchive
polymorphic_test_oarchive;
// required by export BOOST_SERIALIZATION_REGISTER_ARCHIVE( test_oarchive )
or something like this. Now you should have test_oarchive and polymorphic_test_oarchive
That's what I'm doing. So now 'unit' only has a template serialize method, but I still
int main() { unit u(42);
{ std::cout << "template:" << std::endl; test_oarchive ar(std::cout); ar << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; }
{ std::cout << "polymorphic:" << std::endl; polymorphic_test_oarchive ar(std::cout); ar << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; } }
Which outputs:
template:
42 polymorphic: 42
Code is attached. -- Maxime
So now 'unit' only has a template serialize method, but I still
int main() { unit u(42);
{ std::cout << "template:" << std::endl; test_oarchive ar(std::cout); ar << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; }
{ std::cout << "polymorphic:" << std::endl; polymorphic_test_oarchive ar(std::cout); ar << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; } }
Which outputs:
template:
42 polymorphic: 42
Code is attached.
what happens when you try: std::cout << "polymorphic:" << std::endl; polymorphic_oarchive & po = polymorphic_test_oarchive ar(std::cout); po << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; This would actually be using the polymorphic interface as it's intended to be used by routing the serialization through the polymorphic interface. Robert Ramey
On 08/18/2010 08:33 PM, Robert Ramey wrote:
So now 'unit' only has a template serialize method, but I still
int main() { unit u(42);
{ std::cout << "template:" << std::endl; test_oarchive ar(std::cout); ar << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; }
{ std::cout << "polymorphic:" << std::endl; polymorphic_test_oarchive ar(std::cout); ar << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; } }
Which outputs:
template:
42 polymorphic: 42
Code is attached.
what happens when you try:
std::cout << "polymorphic:" << std::endl; polymorphic_oarchive & po = polymorphic_test_oarchive ar(std::cout); po << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl;
This would actually be using the polymorphic interface as it's intended to be used by routing the serialization through the polymorphic interface.
Robert Ramey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I added:
{ std::cout << "polymorphic with polymorphic_oarchive:" << std::endl; polymorphic_test_oarchive ar(std::cout); boost::archive::polymorphic_oarchive & po = ar; po << BOOST_SERIALIZATION_NVP(u); std::cout << std::endl; }
The output is:
template:
42 polymorphic: 42 polymorphic with polymorphic_oarchive: 42
-- Maxime
Hi,
I have a problem with serializing a derived classes through a
pointer to a base class. I tried registering with the syntax from the
documentation:
|ar.template register_type
Look at the documentation regarding LoadConstruct and also the tests for no default ctor. Robert Ramey Dante Stroe wrote:
Hi,
I have a problem with serializing a derived classes through a pointer to a base class. I tried registering with the syntax from the documentation:
ar.template register_type
(); , which works well in case the derived class has a default constructor (just like the example). I just don't know what the syntax is for the case where the derived class does not have a default constructor (if I use the same syntax to register the derived class then I get a compilation error about the fact that there is no. I can provide an example in case this is not clear enough.
Is it an absolute requirement for all derived classes to have a default constructor?
Thank you and best regards, Dante
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Dante Stroe
-
Maxime van Noppen
-
Robert Ramey