Boost序列化映射与比较器

Boost serialize map with comparator

本文关键字:比较器 映射 序列化 Boost      更新时间:2023-10-16

有人能帮助我了解如何序列化地图与比较器。保存后,map知道比较器类,但是map不知道比较器字段。

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

啊。非常好的问题。这是boost中序列化的一个限制。

如果是有状态比较器,则不序列化比较器状态。

在SSCCE中演示这个问题:Live On Coliru,它打印

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

这是有意义的,因为否则将要求所有比较器都是可序列化的。这带来了困难的问题(如果Cmp是std::function<bool(K)>怎么办?如果实际值是一个lambda呢?


所以,长话短说:咬紧牙关,也序列化你的比较器:

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 ordern";
        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 ordern";
        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