Boost logo

Boost Users :

From: wayne.x.liu_at_[hidden]
Date: 2006-03-24 19:03:15


I am trying to use the serialization library to serialize and instantiate
polymorphic objects. I succeeded when serializing and deserializing the
exact objects or using the exact pointer type of the derived classes.
However, I failed when serializing and deserializing using a pointer to
the base class. I would get either unregistered void cast or stream error
or compilation errors or segementation faults.

Perhaps I'm not understanding it correctly, but I believe the library is
supposed to allow this. I saw the demo.cpp program is doing just that
(de/serializing using pointers to bus_stop, the base class).

I tried to narrow down my problem by stripping out demo.cpp to just the
portion that serializes using pointers (removing gps, schedules, routes).
However, doing this caused the program to stop compiling: incomplete type
`boost::STATIC_ASSERTION_FAILURE< false>'

The example seems very simple now. I tried to just remove the unnecessary
classes. (I moved the ia.register_type(static_cast<bus_stop_corner
*>(NULL)); into the save and restore routines.) I'm very confused how
this very simple case doesn't work. Any help is greatly appreciated.

Below is the stripped-down demo.cpp and the error message I got from gcc
3.2.3 and gcc 3.4.4.

Thanks,

Wayne Liu

g++ -c -Wall -g -Iincludes -I/cbb/public/wayne/build/include
-I/cbb/public/wayne/build/include/boost-1_33_1/ -o lib/demo.o
test/demo.cpp
/cbb/public/wayne/build/include/boost-1_33_1/boost/archive/detail/oserializer.hpp:
In function `void boost::archive::save(Archive&, T&) [with Archive =
boost::archive::text_oarchive, T = const bus_stop*]':
/cbb/public/wayne/build/include/boost-1_33_1/boost/archive/basic_text_oarchive.hpp:78:
  instantiated from `void
boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with
T = const bus_stop*, Archive = boost::archive::text_oarchive]'
/cbb/public/wayne/build/include/boost-1_33_1/boost/archive/detail/interface_oarchive.hpp:78:
  instantiated from `Archive&
boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with
T = const bus_stop*, Archive = boost::archive::text_oarchive]'
test/demo.cpp:123: instantiated from here
/cbb/public/wayne/build/include/boost-1_33_1/boost/archive/detail/oserializer.hpp:567:
error: incomplete type `boost::STATIC_ASSERTION_FAILURE< false>' used in
nested name specifier
/cbb/public/wayne/build/include/boost-1_33_1/boost/archive/detail/oserializer.hpp:567:
error: size of array has non-integral type `<type error>'

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

#include <boost/archive/tmpdir.hpp>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>

/////////////////////////////////////////////////////////////
// One bus stop
//
// illustrates serialization of serializable members
//

class bus_stop
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_stop
&gp);
    virtual std::string description() const = 0;
    int latitude;
    int longitude;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & latitude;
        ar & longitude;
    }
protected:
    bus_stop(const int & _lat, const int & _long) :
        latitude(_lat), longitude(_long)
    {}
public:
    bus_stop(){}
    virtual ~bus_stop(){}
};

BOOST_IS_ABSTRACT(bus_stop)

std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
    return os << bs.latitude << bs.longitude << ' ' << bs.description();
}

/////////////////////////////////////////////////////////////
// Several kinds of bus stops
//
// illustrates serialization of derived types
//
class bus_stop_corner : public bus_stop
{
    friend class boost::serialization::access;
    std::string street1;
    std::string street2;
    virtual std::string description() const
    {
        return street1 + " and " + street2;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // save/load base class information
        ar & boost::serialization::base_object<bus_stop>(*this);
        ar & street1 & street2;
    }

public:
    bus_stop_corner(){}
    bus_stop_corner(const int & _lat, const int & _long,
        const std::string & _s1, const std::string & _s2
    ) :
        bus_stop(_lat, _long), street1(_s1), street2(_s2)
    {
    }
};

class bus_stop_destination : public bus_stop
{
    friend class boost::serialization::access;
    std::string name;
    virtual std::string description() const
    {
        return name;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<bus_stop>(*this) & name;
    }
public:
 
    bus_stop_destination(){}
    bus_stop_destination(
        const int & _lat, const int & _long, const std::string & _name
    ) :
        bus_stop(_lat, _long), name(_name)
    {
    }
};

void save(const bus_stop *s, std::stringstream &ss)
{
    std::cout << "original";
    std::cout << *s;
    boost::archive::text_oarchive oa(ss);
oa.register_type(static_cast<bus_stop_corner *>(NULL));
oa.register_type(static_cast<bus_stop_destination *>(NULL));

    oa << s;
}

void
restore( std::stringstream &ss)
{
    bus_stop *s;
    boost::archive::text_iarchive ia(ss);
ia.register_type(static_cast<bus_stop_corner *>(NULL));
ia.register_type(static_cast<bus_stop_destination *>(NULL));
    ia >> s;
    std::cout << "restored";
    std::cout << *s;
}

int main(int argc, char *argv[])
{
    // fill in the data
    // make a few stops
    bus_stop *bs0 = new bus_stop_corner(
        34,
        134,
        "24th Street", "10th Avenue"
    );
    bus_stop *bs1 = new bus_stop_corner(
        35,
        133,
        "State street", "Cathedral Vista Lane"
    );
    bus_stop *bs2 = new bus_stop_destination(
        35,
        133,
        "White House"
    );
    bus_stop *bs3 = new bus_stop_destination(
        35,
        133,
        "Lincoln Memorial"
    );

{
    std::stringstream ss;
    // display the complete schedule
    save(bs0,ss);
    restore(ss);
}

{
    std::stringstream ss;
    // display the complete schedule
    save(bs1,ss);
    restore(ss);
}

{
    std::stringstream ss;
    // display the complete schedule
    save(bs2,ss);
    restore(ss);
}

{
    std::stringstream ss;
    // display the complete schedule
    save(bs3,ss);
    restore(ss);
}

    return 0;
}



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