Boost logo

Boost :

Subject: Re: [boost] [serialization] polymorphic archives +boost_class_exportgenerates linker errors
From: Robert Ramey (ramey_at_[hidden])
Date: 2009-11-28 00:34:26


Christoph Heindl wrote:
> #include <boost/archive/xml_iarchive.hpp>
> #include <boost/archive/polymorphic_iarchive.hpp>
> #include <boost/archive/polymorphic_oarchive.hpp>
> #include <boost/serialization/export.hpp>
> #include "demo_polymorphic_A.hpp"
> BOOST_CLASS_EXPORT(A);
>
> the compiler breaks with "cannot convert parameter 1 from
> 'boost::archive::xml_iarchive' to
> 'boost::archive::polymorphic_iarchive &" in
> 'boost/serialization/access.hpp'

I took this example and indeed it failed to compile. It
took me quite a while to discover the cause.

demo_polymorphic_A.hpp includes

class A {
    ...
    void serialization(boost::archive::polymorphic_iarchive &ar, const
unsigned version);
    ...
};

When BOOST_CLASS_EXPORT(A) is encountered, it attempts to "register"
All the archives included. This means xml_iarchive with the type A. But
class A includes declaration only for polymorphic_iarchive. So during the
"register" process, it tries to convert a reference to xml_iarchive to a
reference to polymorphic_iarchive - which fails with a compile time error.

So the appropriate fix is not to include xml_iarchive - (maybe to enforce
the usage of polymorphic archives all the time- or whatever reason) or
use replace the serialize above with:

ttemplate<class Archive>
void serialize(Archive & ar, const unsigned int version);

This WILL compile without problem. However it will fail to link as
the serialization function will not have been instantiated with
xml_iarchive.

This can be addressed by altering demo_polymorphic_A.cpp to look
like the following:

#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/polymorphic_oarchive.hpp>
#include "demo_polymorphic_A.hpp"
// explicitly instantiate templates for polymorphic archives
// used by this demo.
template
void A::serialize<boost::archive::polymorphic_iarchive>(
    boost::archive::polymorphic_iarchive &,
    const unsigned int
);
template
void A::serialize<boost::archive::polymorphic_oarchive>(
    boost::archive::polymorphic_oarchive &,
    const unsigned int
);

This will compiler and link as expected. Perhaps this
explanation will help with your own application. At the
bottom of its is the EXPORT(A) requires that templates
or declarations exist which match all archive classes
included.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk