Summit
Summit

Reputation: 2268

Boost XML archiving compiling error with polymorphic classes

I am trying to save my files in XML format using boost archiving.

I get these two errors at compile time.

  1. Error C2664 'int boost::mpl::assertion_failed(boost::mpl::assert::type)': cannot convert argument 1 from 'boost::mpl::failed ***********boost::serialization::is_wrapper:: ***********' to 'boost::mpl::assert::type'

  2. Error C2789 'mpl_assertion_in_line_6': an object of const-qualified type must be initialized

This happens because of these two lines.

BOOST_CLASS_EXPORT_GUID(SumKeyframeXYZ, "SumKeyframeXYZ")
BOOST_CLASS_EXPORT_GUID(SumPosition_Channel, "SumPosition_Channel")

This is the Main function.

#include "Container.h"

BOOST_CLASS_EXPORT_GUID(SumKeyframeXYZ, "SumKeyframeXYZ")
BOOST_CLASS_EXPORT_GUID(SumPosition_Channel, "SumPosition_Channel")

int main()
{
    std::ofstream ofs("D:\\output.xml");
    Container cont;
    cont.AddPositionChannel();
    boost::archive::xml_oarchive oa(ofs);
    oa << BOOST_SERIALIZATION_NVP(cont);
    return 0;
}

This is how the classes structure looks like.

Container.h

#include <string>
#include "SumChannel.h"
#include "SumPosition_Channel.h"
#include <fstream>
#include <iostream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>

class Container
{
private:
    std::string stdstrName;
    std::vector<std::shared_ptr<SumChannel>> Channels;

public:
    Container() { stdstrName = "Container Name"; }
    void AddPositionChannel() {
        std::shared_ptr< SumPosition_Channel> posChannel = std::make_shared<SumPosition_Channel>();
        Channels.push_back(posChannel);
    };


private:

    friend class boost::serialization::access;
    template<class Archive> void serialize(Archive & ar,
        const unsigned int version) const {
        ar & BOOST_SERIALIZATION_NVP(stdstrName);
        ar & BOOST_SERIALIZATION_NVP(Channels);
    }

};

//////////////////////////////////////////////////////////

SumChannel.h

#include <fstream>
#include <iostream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/vector.hpp>

class SumChannel
{
public:
    float offset;

    SumChannel() { offset = 1.0; }

private:

    friend class boost::serialization::access;

    template<class Archive> void serialize(Archive & ar,
        const unsigned int version) const {
            ar & BOOST_SERIALIZATION_NVP(offset);   
    }
};

SumPosition_Channel

#include "SumKeyframeXYZ.h"
#include "SumChannel.h"
#include <vector>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/vector.hpp>

class SumPosition_Channel : public SumChannel
{
public:
    std::vector<SumKeyframeXYZ>  keyframes;

    void AddKeyframe() { SumKeyframeXYZ key; keyframes.push_back(key); }

private:
    friend class boost::serialization::access;
    
    typedef SumChannel _Super;
    template<class Archive> void serialize(Archive & ar,
        const unsigned int version) const {
        ar & boost::serialization::base_object<_Super>(*this);
        ar & BOOST_SERIALIZATION_NVP(keyframes);
    }
};

KeyFrameBase.h

#include <iostream>
#include <fstream>

#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
class Keyframebase
{
public:
    std::string stdstrName;
    float time;

    Keyframebase() { stdstrName = "BaseKey"; time = 50.0; }
    
private:

    friend class boost::serialization::access;

    template<class Archive> void serialize(Archive & ar,
        const unsigned int version) {
        ar & BOOST_SERIALIZATION_NVP(stdstrName);
        ar & BOOST_SERIALIZATION_NVP(time);
    }

};

SumKeyframeXYZ.h

#include "KeyframeBase.h"
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/vector.hpp>

class SumKeyframeXYZ : public Keyframebase
{
public:
    float x;
    float y;
    float z;

    SumKeyframeXYZ() { x = 150.0; y = 200.0; z = 300.0; }

private:
    friend class boost::serialization::access;

    template<class Archive> void serialize(Archive & ar,
        const unsigned int version) const {
        ar & boost::serialization::base_object<Keyframebase>(*this);
        ar & BOOST_SERIALIZATION_NVP(x);
        ar & BOOST_SERIALIZATION_NVP(y);
        ar & BOOST_SERIALIZATION_NVP(z);
    }
};

Upvotes: 2

Views: 256

Answers (1)

Summit
Summit

Reputation: 2268

The issue with the code was that i was not writing NVP to the base class

I changed the Base class archiving code from

  ar & boost::serialization::base_object<_Super>(*this);

to this for all the base classes.

typedef SumChannel _Super;
ar & boost::serialization::make_nvp("SumChannel", boost::serialization::base_object<_Super>(*this));

and removed the const from the serilize function.

Upvotes: 2

Related Questions