Question

I'm working on ubuntu 12.04LTS and using clang 3.4.

I have a CMake project and want to use the boost serialization library. I downloaded boost 1.55.0 from SourceForge.

My project folder tree looks like:

MyProject
    |    Source
    |       |    main.cpp
    |       |    CMakeLists.txt
    |    Build
    |    Libraries
    |       |    Boost1p55p0
    |       |         |    boost
    |       |         |    ...other boost data
    |       |         |    build
    |       |         |       |    include
    |       |         |       |    lib

So in the Boost1p55p0 directory I made a new directory build, so that bootstrap looked like:

./bootstrap.sh --prefix=build/

Then I did

./b2

and

./b2 install

So the minimal not-working example is:

CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)

set( CMAKE_C_COMPILER clang )
set( CMAKE_CXX_COMPILER clang++ )
set( CMAKE_LINKER llvm-link )

project (Test)
include_directories( ${PROJECT_SOURCE_DIR} ../Libraries/Boost1p55p0/build/include )

set( sources ${sources} main )

add_executable(Test ${sources})

set( OperatingSystem "Linux" )
set( CMAKE_CXX_FLAGS "-std=c++11" )

find_library( PATH_TO_BoostSerialization boost_serialization ../Libraries/Boost1p55p0/build/lib/ )

target_link_libraries (Test ${PATH_TO_BoostSerialization})

main.cpp (from the tutorial but with xml archives) :

#include <fstream>
#include <string>

// include headers that implement a archive in simple text format
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
{
    private:
        friend class boost::serialization::access;

        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & degrees;
            ar & minutes;
            ar & seconds;
        }
        int degrees;
        int minutes;
        float seconds;
    public:
        gps_position(){};
        gps_position(int d, int m, float s) :
            degrees(d), minutes(m), seconds(s){}
};

int main() {
    std::string inFileName = "testIn.xml";
    std::string outFileName = "testOut.xml";
    // create and open a character archive for output
    std::ofstream ofs(outFileName);

    // create class instance
    const gps_position g(35, 59, 24.567f);

    // save data to archive
    {
        boost::archive::xml_oarchive oa(ofs);
        // write class instance to archive
        oa << g;
    }

    return 0;
}

And now I get the following compiler error:

[cut off directory tree here]Boost1p55p0/build/include/boost/archive/basic_xml_oarchive.hpp:92:9: error: no matching function for call to
  'assertion_failed'
    BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[cut off directory tree here]Boost1p55p0/build/include/boost/mpl/assert.hpp:287:11: note: expanded from macro 'BOOST_MPL_ASSERT'
      boost::mpl::assertion_failed<false>( \

I don't have any idea where the error is. I'blessed if I know.

Many thanks in advance

Was it helpful?

Solution

Ah, I just noticed you mentioned the only important bit here, hidden in a small aside:

main.cpp (from the tutorial but with xml archives)

Xml archives need names for their elements!

Name-Value Pairs

XML archives present a somewhat special case. XML format has a nested structure that maps well to the "recursive class member visitor" pattern used by the serialization system. However, XML differs from other formats in that it requires a name for each class data member. Our goal is to add this information to the class serialization specification while still permiting the the serialization code to be used with any archive.

Our solution is to wrap class members to be serialized in a name-value-pair. This structure is defined in nvp.hpp. It is just a reference to the data member coupled with a pointer to to a const char * which corresponds to the XML name. It implements the default serialization functions for a name-value pair. This default action is to just ignore the item name and serialize the data value in the normal manner. For archive classes that don't make any special provision for name-value pairs, this is the action which will be invoked when the name-value pair is serialized. Hence, wrapping a data value into a name-value pair will have no effect when used with archives which make no special provision for this wrapper.

See, looking at demo_xml.cpp, add:

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

and

boost::archive::xml_oarchive oa(ofs);
// write class instance to archive
oa << BOOST_SERIALIZATION_NVP(g);

See it Live on Coliru

Output:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<g class_id="0" tracking_level="0" version="0">
    <degrees>35</degrees>
    <minutes>59</minutes>
    <seconds>24.566999</seconds>
</g>
</boost_serialization>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top