Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializing an STL map of structures

I'm trying to serialize an STL map where the key and value are structures. The attached code works fine when the key is a structure and the value is an int. However, I'm having problems setting up the serialize function to handle a structure value. Any suggestions as to how to do this?

Many thanks - Andrew.

#include <string>
#include <fstream>
#include <algorithm>
#include <map>
#include <unordered_map>
#include <iostream>
#include <chrono>
#include <sstream>
#include <functional>

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/unordered_map.hpp>
#include <boost/serialization/version.hpp>

using namespace std;

struct portfolio_data {
    double a;
};

struct portfolio_key {
    long id;
    string name;
};

struct portfolio_compare
{
    bool operator() ( portfolio_key k1, portfolio_key k2 ) const
    {
        return (
                   ( k1.id < k2.id ) ||
                   ( ( k1.id == k2.id ) && ( k1.name < k2.name ) )
               );
    }
};

typedef map<portfolio_key, int, portfolio_compare> portfolio_map;

//------------------------------------------------------------------------

template<class Archive>
void serialize( Archive& ar, portfolio_key& key, const unsigned int version )
{
    ar & boost::serialization::make_nvp( "id", key.id );
    ar & boost::serialization::make_nvp( "name", key.name );
}

//------------------------------------------------------------------------

void save( portfolio_map& map_var, const std::string& file_name )
{
    ofstream ofs( file_name.c_str(), ios::out | ios::binary );
    boost::archive::binary_oarchive ba( ofs ); // works for text too
    ba << BOOST_SERIALIZATION_NVP( map_var );
}

//------------------------------------------------------------------------

portfolio_map load( const std::string& file_name )
{
    portfolio_map map_var;
    ifstream ifs( file_name.c_str(), ios::in | ios::binary );
    boost::archive::binary_iarchive ba( ifs );
    ba >> BOOST_SERIALIZATION_NVP( map_var );
    return map_var;
}

//------------------------------------------------------------------------

int main( void )
{
    portfolio_map map1;

    for ( long i = 0; i < 10; ++i )
    {
        portfolio_key k;
        k.id = i;
        k.name = "AAAAA";

        portfolio_data d;
        map1[k] = i;
    }

    save( map1, "map.bin" );

    portfolio_map map2;
    map2 = load( "map.bin" );

    cout << map2.size() << endl;
}
like image 349
Andrew Colin Avatar asked Nov 09 '22 00:11

Andrew Colin


1 Answers

You just forgot to define serialize for your value struct, that's all:

template<class Archive>
void serialize( Archive& ar, portfolio_data& value, const unsigned int  version )
{
    ar & boost::serialization::make_nvp( "a", value.a );
}
like image 68
PiotrNycz Avatar answered Nov 15 '22 07:11

PiotrNycz