2015-07-22 8 views
1

Может кто-нибудь помочь мне понять, как сериализовать карту с компаратором. После сохранения карты знает класс компараторов, но карта не знает о полях компараторов.Boost сериализуйте карту компаратором

bool operator() (const ScalarT &a, const ScalarT &b) const{ 
    return (a - someField < b); 
} 
+0

Вы должны добавить SSCCE в следующий раз. Было довольно сложно понять, что вы имели в виду – sehe

ответ

0

Ah. Отличный вопрос. В этом случае ограничение сериализации в boost.

Он не сериализует состояние компаратора в случае сравнения состояния.

Демонстрируя вопрос в SSCCE: Live On Coliru, который печатает

====== original order 
3 -> three 
2 -> two 
1 -> one 
====== deserialized order 
1 -> one 
2 -> two 
3 -> three 

Это имеет некоторый смысл, так как в противном случае делать бы требовать от всех компараторов быть сделаны сериализации. И это вызывает hard проблемы (что, если Cmp std::function<bool(K)>? Что, если фактическое значение - лямбда?).


Так, короче говоря: стиснуть зубы и просто сериализовать компаратор тоже:

Live On Coliru

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/map.hpp> 
#include <iostream> 
#include <sstream> 

template <typename T> 
struct StateFullCmp { 
    bool invert_; 
    StateFullCmp(bool invert) : invert_(invert) {} 

    bool operator()(T const&a, T const& b) const { 
     return invert_? (b<a) : (a<b); 
    } 
}; 

namespace boost { namespace serialization { 
    template <typename Ar, typename T> 
     void serialize(Ar& ar, StateFullCmp<T>& cmp, unsigned) { 
      ar & cmp.invert_; 
     } 
} } 

int main() { 
    using MyMap = std::map<int, std::string, StateFullCmp<int> >; 
    std::stringstream ss; 

    { 
     MyMap const m { 
      { { 1, "one" }, { 2, "two" }, { 3, "three" } }, 
      StateFullCmp<int> { true } // inverted order 
     }; 

     std::cout << "====== original order\n"; 
     for (auto& e : m) 
      std::cout << e.first << " -> " << e.second << "\n"; 

     boost::archive::text_oarchive oa(ss); 
     auto cmp_copy = m.key_comp(); 
     oa << cmp_copy << m; 
    } 

    { 
     boost::archive::text_iarchive ia(ss); 

     MyMap::key_compare cmp_state { false }; // default initialization 
     ia >> cmp_state; 

     MyMap deserialized(cmp_state); 
     ia >> deserialized; 

     std::cout << "====== deserialized order\n"; 
     for (auto& e : deserialized) 
      std::cout << e.first << " -> " << e.second << "\n"; 
    } 
} 

Теперь печатает:

====== original order 
3 -> three 
2 -> two 
1 -> one 
====== deserialized order 
3 -> three 
2 -> two 
1 -> one 
Смежные вопросы