Boost logo

Boost Users :

Subject: Re: [Boost-users] [serialization] Different behaviors between archive and its polymorphic variant
From: Robert Ramey (ramey_at_[hidden])
Date: 2010-08-18 12:42:12


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<test_oarchive>
{
    friend class boost::archive::save_access;
    friend class boost::archive::detail::interface_oarchive<test_oarchive>;
public:
    test_oarchive(std::ostream& out, unsigned int = 0) : out_(out){ }
    void save_binary(const void* address, std::size_t count) {
out_.write(static_cast<const char*>(address), count); }
    template <typename T>
    void save(const T& t){
        out_ << t;
    }
    template <class T>
    void save_override(const boost::serialization::nvp<T>& nvp, int f)
    {
        out_ << "<name=" << nvp.name() << ">";
        typedef boost::archive::detail::common_oarchive<test_oarchive>
detail_common_oarchive;
        this->detail_common_oarchive::save_override(nvp.const_value(), f);
        out_ << "</name=" << nvp.name() << ">\n";
    }
    void save_override(const boost::archive::object_id_type & t, int) { }
    void save_override(const boost::archive::object_reference_type & t, int)
{ }
    void save_override(const boost::archive::version_type & t, int) { }
    void save_override(const boost::archive::class_id_type & t, int) { }
    void save_override(const boost::archive::class_id_optional_type & t,
int) { }
    void save_override(const boost::archive::class_id_reference_type & t,
int) { }
    void save_override(const boost::archive::class_name_type & t, int) { }
    void save_override(const boost::archive::tracking_type & t, int) { }
private:
    std::ostream& out_;
};

Test the above to verify that it works according to your taste.

Now use a "templated typedef" to generate the polymorphic version:

#include <boost/config.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>

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

Robert Ramey


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net