简体   繁体   中英

serialize std::unordered_map < int, std::unordered_set<int> > with boost

I try to serialize/deserialize std::unordered_map < int, std::unordered_set<int> > when I look at boost/serialization/map.hpp it seems to be simple (even tough I dont understand it quite) The following code seems to compile for serialization but fails for deserialization.

Does somebody know how to do this properly, or can point to some documentation of these STL serialization techniques? I have not found something unfortunately...

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <boost/serialization/map.hpp>
#include <boost/serialization/collections_save_imp.hpp>
#include <boost/serialization/collections_load_imp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/split_free.hpp>

namespace boost { namespace serialization {

    template<class Archive, typename... TArgs >
        inline void save(Archive & ar, std::unordered_map<TArgs...> const&t, unsigned) {
            boost::serialization::stl::save_collection<Archive, std::unordered_map<TArgs...> >(ar, t);
        }

    template<class Archive, typename... TArgs >
        inline void load(Archive & ar, std::unordered_map<TArgs...> &t, unsigned) {
            boost::serialization::stl::load_collection<Archive,
                std::unordered_map<TArgs...>,
                boost::serialization::stl::archive_input_map<
                    Archive, std::unordered_map<TArgs...> >,
                boost::serialization::stl::no_reserve_imp<std::unordered_map<TArgs...> >
                    >(ar, t);
        }

    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template <class Archive, typename... TArgs>
        inline void serialize(Archive & ar, std::unordered_map<TArgs...> &t, unsigned file_version) {
            boost::serialization::split_free(ar, t, file_version);
        }
} }


namespace boost { namespace serialization {

    template<class Archive, typename... TArgs >
        inline void save(Archive & ar, std::unordered_set<TArgs...> const&t, unsigned) {
            boost::serialization::stl::save_collection<Archive, std::unordered_set<TArgs...> >(ar, t);
        }

    template<class Archive, typename... TArgs >
        inline void load(Archive & ar, std::unordered_set<TArgs...> &t, unsigned) {
            boost::serialization::stl::load_collection<Archive,
                std::unordered_set<TArgs...>,
                boost::serialization::stl::archive_input_map<
                    Archive, std::unordered_set<TArgs...> >,
                boost::serialization::stl::no_reserve_imp<std::unordered_set<TArgs...> >
                    >(ar, t);
        }

    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template <class Archive, typename... TArgs>
        inline void serialize(Archive & ar, std::unordered_set<TArgs...> &t, unsigned file_version) {
            boost::serialization::split_free(ar, t, file_version);
        }
} }


int main()
{

    std::stringstream ss;
    boost::archive::binary_oarchive oa2(ss, boost::archive::no_codecvt | boost::archive::no_header);

    std::unordered_map<int, std::unordered_set<int> > s, out;
    s.emplace( 0, std::unordered_set<int>{9,19} );

    oa2 << s;

    // Try to load this!!
    //boost::archive::binary_iarchive ia2(ss, boost::archive::no_codecvt | boost::archive::no_header);
    //ia2 >> out;
}

http://coliru.stacked-crooked.com/a/663c0ce7bf632f85

Boost already contains methods for serializing std::unordered_map and std::unordered_set since version 1.5.6 (in fact they were added in February 2014 )

So there is no need to write them yourself:

#include <map>
#include <sstream>

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/unordered_map.hpp>
#include <boost/serialization/unordered_set.hpp>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

int main()
{
  std::stringstream ss;

  std::unordered_map<int, std::unordered_set<int> > s, out;
  s.emplace( 0, std::unordered_set<int>{9,19} );
  boost::archive::text_oarchive oarch(ss);
  oarch << s;
  boost::archive::text_iarchive iarch(ss);
  iarch >> out;
  std::cout << (s == out) << std::endl;
}

live on coliru

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM