boost::serialization - Serialization (non intrusive) of a map containing in and structure.

I am using boost 1.41.0 and MS VS 2008. I have been having trouble serializing a map which contains a int (key) and structure value. I create a simple test app to aid in the discussion. I am attempting to perform a non intrusive serialization of the structure. I had in the past been able to serialize a map of <int,string> successfully, but now that the map is <int, non_intrusive> where non_intrusive is the name of my strut, I get an error: 2>Windows-6.1\install\include\boost-1_41\boost/serialization/access.hpp(109) : error C2039: 'serialize' : is not a member of 'non_intrusive' and the line in boost is: template<class Archive, class T> static void serialize( Archive & ar, T & t, const unsigned int file_version ){ t.serialize(ar, file_version); // serialize( ar, t, file_version ); } Where if I change the line t.serialize(ar, file_version); to serialize( ar, t, file_version ); and then it compiles. Which of course I know I should not do, but only did so to see if I could get it to call my template specialization for my serialize code of my strut with out having to perform in intrusive serialization and agian was just a test to see if boost would call my serialize function. I have revered this so fear not... this is not the problem. namespace boost { namespace serialization { template<class Archive> void serialize( Archive& ar, non_intrusive& ni ){ ar & ni.a; } which is of course wrapped in the boost::serialization namespace... full example below I am guessing I have not done something correctly and I have been successful in the past as I said serializing structures, vectors, and maps. This is the first time I tried to serialize a map with a struct. I also converted my code (not the example) to use a vector of std::pair<int, non_intrusive> and got the same error. Here is the full program listing any help would be appreciated: //------------------------------------------------------------------------------------------- #include <string> #include <fstream> #include <algorithm> #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> #include <boost/serialization/utility.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/map.hpp> struct non_intrusive{ int id; std::string name; }; typedef std::map<int, non_intrusive> a_map_t; namespace boost { namespace serialization { // Not sure if I need to do this bit, but I have seen references to this // syntax on the web. template<class Archive> void serialize( Archive& ar, std::pair<int, non_intrusive> & ni_pair ){ ar & std::pair<int, non_intrusive>( ni_pair ); } template<class Archive> void serialize( Archive& ar, non_intrusive& ni ){ ar & ni.a; } }} void save ( const a_map_t& map_var, const std::string& file_name ) { boost::filesystem::path file_path = file_name; boost::filesystem::path pathstr = file_path.remove_leaf(); if( pathstr != "" ) boost::filesystem::create_directory( pathstr ); std::ofstream ofs( file_name.c_str(), std::ios_base::out | std::ios_base::trunc); boost::archive::xml_oarchive xml(ofs); xml << BOOST_SERIALIZATION_NVP( map_var ); } // +---------------------------------------------------------------------- a_map_t load(const std::string& file_name) { a_map_t map_var; // std::ifstream ifs(file_name.c_str(), std::fstream::binary | std::fstream::in); std::ifstream ifs(file_name.c_str() ); if( !ifs ) { non_intrusive od; od.id = -1; od.name = "unknown device"; map_var.insert( a_map_t::value_type( 0, od ) ); save( map_var, file_name ); }else { boost::archive::xml_iarchive xml(ifs); xml >> BOOST_SERIALIZATION_NVP( map_var ); } return map_var; } // +---------------------------------------------------------------------- int main( void ){ a_map_t map; map = load("map.xml"); save(map, "map.xm" ); }

Thanks Steven for the reply. While this was not the final answer to the problem (as it was one problem) it did help lead to the solution which was as Steven stated ..... and a missing nvp around the ni.a variable. Note the std::pair<> code was not necessary and was removed. below is working version and xml file for those who may experience this in the future. ------------------------------------------------------------------------ #include <string> #include <fstream> #include <algorithm> #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> #include <boost/serialization/utility.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/map.hpp> #include <boost/serialization/version.hpp> struct non_intrusive{ int id; std::string name; }; typedef std::map<int, non_intrusive> a_map_t; namespace boost { namespace serialization { template<class Archive> void serialize( Archive& ar, non_intrusive& ni, const unsigned int version ){ ar & boost::serialization::make_nvp( "id", ni.id ); ar & boost::serialization::make_nvp( "name", ni.name ); } }} // +---------------------------------------------------------------------- void save ( const a_map_t& map_var, const std::string& file_name ) { boost::filesystem::path file_path = file_name; boost::filesystem::path pathstr = file_path.remove_leaf(); if( pathstr != "" ) boost::filesystem::create_directory( pathstr ); std::ofstream ofs( file_name.c_str(), std::ios_base::out | std::ios_base::trunc); boost::archive::xml_oarchive xml(ofs); xml << BOOST_SERIALIZATION_NVP( map_var ); } // +---------------------------------------------------------------------- a_map_t load(const std::string& file_name) { a_map_t map_var; // std::ifstream ifs(file_name.c_str(), std::fstream::binary | std::fstream::in); std::ifstream ifs(file_name.c_str() ); if( !ifs ) { non_intrusive od; od.id = -1; od.name = "unknown device"; map_var.insert( a_map_t::value_type( 0, od ) ); save( map_var, file_name ); }else { boost::archive::xml_iarchive xml(ifs); xml >> BOOST_SERIALIZATION_NVP( map_var ); } return map_var; } // +---------------------------------------------------------------------- int main( void ){ a_map_t map; map = load("map.xml"); save(map, "map.xm" ); } ------------------------------------------------------------------------ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="6"> <map_var class_id="0" tracking_level="0" version="0"> <count>1</count> <item_version>0</item_version> <item class_id="1" tracking_level="0" version="0"> <first>0</first> <second class_id="2" tracking_level="0" version="0"> <id>-1</id> <name>unknown device</name> </second> </item> </map_var> </boost_serialization>
participants (2)
-
Brian Davis
-
Steven Watanabe