Search code examples
c++boostdictionaryboost-serialization

How to serialize a (nested) map to a variable using boost?


I have a map declared inside a class as follows:

class Example {
    public:
        Example()
        {
            std::map< std::string, std::string > map_data;
            map_data["LOCATION"] = "USA";
            map_data["WEBSITE"] = "http://www.google.com/";

            custom_map["nickb"] = map_data;
        }
        std::map< std::string, std::map< std::string, std::string > > get_map() { return custom_map; }
    private:
        std::map< std::string, std::map< std::string, std::string > > custom_map;

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

And I'd like to be able to serialize just the map it to a variable using boost.

The examples seem to be serializing the entire class, which I do not need to do. They're also writing to a file, which seems inefficient to me, as I do not need to archive the state of the map to a file, just represent it in a way that can be restored later.

Right now I have this to save the map:

// Create an Example object
Example obj;

// Save the map
std::stringstream outstream( std::stringstream::out | std::stringstream::binary);
boost::archive::text_oarchive oa( outstream);
oa << obj; // <-- BOOST SERIALIZATION STATIC WARNING HERE

// Map saved to this string:
std::string saved_map = outstream.str();

And this to restore it:

// Now retore the map
std::map< std::string, std::map< std::string, std::string > > restored_map;
std::stringstream instream( saved_map, std::stringstream::in | std::stringstream::binary);
boost::archive::text_iarchive ia( instream);
ia >> restored_map;

std::map< std::string, std::string > map_data = restored_map.find( "nickb")->second;
std::cout << "nickb " << map_data["LOCATION"] << " " << map_data["WEBSITE"] << std::endl;

But it is not working. Can anybody give me some tips or show me how to serialize and restore the map?

Thank you.

Edit: I've updated my example with more detail and taken into consideration the answers from K-ballo and Karl Knechtel (Thank you!). This has solved almost all of the errors except one, which is a boost serialization static warning at the above commented line. The warning is:

[Warning] comparison between signed and unsigned integer expressions 

Any idea how to resolve this warning so it compiles? Thanks!

Edit: My problem was twofold: I needed to add: BOOST_CLASS_TRACKING( Example, track_never) And I was serializing the whole class, and trying to unserialize a map.


Solution

  • It looks like you have two completely separate stringstream objects: one of which receives the data, and a second (with no underlying string data) from which you attempt to restore the data. A stringstream isn't data storage anyway; a string is - in much the same way that an fstream writes to a file on disk which is the actual storage.

    Grab the .str() of the stream that you're saving to, and use it to initialize the stream that you read from.