I would be very suspicious of
BOOST_SERIALIZATION_BASE_OBJECT_NVP(AbstractTemplate<std::string>)
since the "name" is taken from the argument. Look
at this macro definition and
expand it by hand.
If you car run under the debugger that would also
indicate the call tree which
would be useful.
Robert Ramey
Hi,
I'm
having some trouble using the Serialization library with a class derived from
an abstract template (example code below). What I'd like to do is
serialize instances of the derived type through a base class pointer
(polymorphic) using the XML archive. The code below works fine using
both the text and binary archives, but fails at runtime with the XML
archive. The exception thrown is boost::archive::xml_archive_exception
with the message "uninitialized exception".
My environment:
GCC
4.1.2 on RHEL 5.3
Boost v1.37
I've also attempted to use Boost 1.40
(although I didn't see anything to suggest relevant changes), which results in
link errors (undefined references to members of
boost::archive::detail::archive_serializer_map<boost::archive::xml_iarchive>
and boost::serialization::void_cast_detail::void_caster among
others).
Any help would be appreciated.
Thanks.
#include <iostream>
#include
<string>
#include <sstream>
#include
<boost/serialization/serialization.hpp>
#include
<boost/archive/xml_iarchive.hpp>
#include
<boost/archive/xml_oarchive.hpp>
#include
<boost/serialization/export.hpp>
class
AbstractBase
{
public:
AbstractBase(const std::string&
n):name(n) {}
virtual ~AbstractBase() {}
virtual
std::ostream& print(std::ostream& os) const =
0;
protected:
AbstractBase():name("UNKNOWN BASE")
{}
friend class boost::serialization::access;
template<class Archive> void serialize(Archive& ar, const uint32_t
version)
{
ar &
BOOST_SERIALIZATION_NVP(name);
}
std::string
name;
};
template <class T>
class AbstractTemplate : public
AbstractBase
{
public:
AbstractTemplate(const std::string&
n):AbstractBase(n) {}
virtual ~AbstractTemplate() {}
virtual void doSomething(const T& t) = 0;
protected:
AbstractTemplate():AbstractBase("UKNOWN TEMPLATE") {}
friend
class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const uint32_t version)
{
ar &
BOOST_SERIALIZATION_BASE_OBJECT_NVP(AbstractBase);
}
};
class Derived : public
AbstractTemplate<std::string>
{
public:
Derived(const
std::string& n):AbstractTemplate<std::string>(n) {}
virtual ~Derived() {}
std::ostream& print(std::ostream&
os) const { return os << "Derived name: " << name <<
std::endl; }
void doSomething(const std::string& str) {
print(std::cout << str << ": "); }
protected:
Derived():AbstractTemplate<std::string>("UNKNOWN DERIVED")
{}
friend class boost::serialization::access;
template<class Archive> void serialize(Archive& ar, const uint32_t
version)
{
ar &
BOOST_SERIALIZATION_BASE_OBJECT_NVP(AbstractTemplate<std::string>);
}
};
BOOST_CLASS_EXPORT(Derived)
namespace boost
{
template <>
struct is_abstract<AbstractBase
>
{
typedef mpl::bool_<true> type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<class
T>
struct is_abstract<AbstractTemplate<T> >
{
typedef mpl::bool_<true> type;
BOOST_STATIC_CONSTANT(bool,
value = true);
};
} // namepsace boost
int main(int
argc, char** argv)
{
static const char XML_NAME[] =
"Stuff";
Derived* d = new Derived("test 1");
AbstractTemplate<std::string>* at = d;
AbstractBase* ab =
d;
std::cout << "before serialization:" <<
std::endl;
d->doSomething("something");
at->print(std::cout);
ab->print(std::cout);
/*
serialization */
std::stringstream ss;
{
boost::archive::xml_oarchive
xmlOut(ss);
xmlOut <<
boost::serialization::make_nvp(XML_NAME, ab);
}
delete
ab;
ab = NULL;
std::cout << "Serialization:"
<< std::endl
<<
ss.str() << std::endl;
/* deserialization */
{
boost::archive::xml_iarchive
xmlIn(ss);
xmlIn >>
boost::serialization::make_nvp(XML_NAME, ab);
}
at =
dynamic_cast<AbstractTemplate<std::string>*>(ab);
d =
dynamic_cast<Derived*>(ab);
if ((ab ==
NULL)
|| (at == NULL)
|| (d ==
NULL))
{
std::cout << "deserialization
failed" << std::endl;
return
EXIT_FAILURE;
}
std::cout << "after
deserialization:" << std::endl;
d->doSomething("something");
at->print(std::cout);
ab->print(std::cout);
delete ab;
return
EXIT_SUCCESS;
}
_______________________________________________
Boost-users mailing
list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users