Boost ICL和Boost序列化的组合

Combination of Boost ICL and Boost Serialization

本文关键字:Boost 组合 ICL 序列化      更新时间:2023-10-16

我试图使用Boost序列化库来归档Boost ICL间隔集(因为我找不到任何其他或多或少的标准方法来序列化它们)。我想把serialize函数分成两个函数saveload。很抱歉,我现在被困在load函数中——我甚至不能保存间隔集的大小。我的测试程序如下。编译器抱怨A << IS.iterative_size()行,这是奇怪的,因为iterative_size()函数的返回类型是size_t

#include <fstream>
#include <string>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/icl/discrete_interval.hpp>
#include <boost/icl/interval_set.hpp>
const std::string Filename = "tmp.archive";
typedef boost::icl::discrete_interval<int> Interval;
typedef boost::icl::interval_set<int> IntervalSet;
namespace boost
{
  namespace serialization
  {
    template<class Archive>
    void save(Archive& A, const IntervalSet& IS, const unsigned int)
    {
      A << IS.iterative_size();
      // ...
    }
    template<class Archive>
    void load(Archive& A, IntervalSet& IS, const unsigned int)
    {
      // ...
    }
    template<class Archive>
    inline void serialize(Archive& A, IntervalSet& IS, const unsigned int V)
    {
      split_free(A, IS, V); 
    }
  }
}
int main()
{
  std::ofstream f(Filename);
  if (f.good())
  {
    boost::archive::binary_oarchive oa(f);
    IntervalSet s;
    s += Interval::closed(100, 200); 
    oa << s;
    f.close();
  }
  else
  {
    std::cout << "Error" << std::endl;
  }
}

任何想法吗?

(编译器- GCC 4.8.1, Boost - 1.55.0, OS - Xubuntu 3.11)

iterative_size()不返回lvalue,这是必需的。无论如何,您都无法有效地反序列化派生属性(就像vector不会(反)序列化size()成员结果一样)。相反,它序列化所有数据,并且size()最终恰好是相同的。

也看

如果没有这样的默认构造函数,则必须重写函数模板load_construct_datasave_construct_data。下面是一个简单的例子

从docs

在对象实例只从(非默认的)构造函数参数初始化的情况下,可以使用它。

Update这里是一个演示实现:Live On Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/icl/discrete_interval.hpp>
#include <boost/icl/interval_set.hpp>
namespace boost { namespace serialization {
    template <typename Archive, typename V>
        void save(Archive& ar, boost::icl::discrete_interval<V> const& di, unsigned) {
            auto const& bb = di.bounds().bits();
            auto const& l  = di.lower();
            auto const& u  = di.upper();
            ar << bb << l << u;
        }
    template <typename Archive, typename V>
        void load(Archive& ar, boost::icl::discrete_interval<V>& di, unsigned) {
            auto bb = di.bounds().bits();
            V    l, u;
            ar >> bb >> l >> u;
            di = boost::icl::discrete_interval<V>(l, u, boost::icl::interval_bounds(bb));
        }
    template <typename Archive, typename V>
        void serialize(Archive& ar, boost::icl::discrete_interval<V>& di, unsigned v) {
            split_free(ar, di, v);
        }
    template <typename Archive, typename V>
        void save(Archive& ar, boost::icl::interval_set<V> const& is, unsigned) {
            auto sz = is.iterative_size();
            ar & sz;
            for (auto& di : is) ar & di;
        }
    template <typename Archive, typename V>
        void load(Archive& ar, boost::icl::interval_set<V>& is, unsigned) {
            is.clear();
            size_t sz;
            ar & sz;
            size_t counter = sz;
            while (counter--) {
                typename boost::icl::interval_set<V>::value_type di;
                ar & di;
                is.insert(is.end(), di);
            }
            assert(is.iterative_size() == sz);
        }
    template <typename Archive, typename V>
        void serialize(Archive& ar, boost::icl::interval_set<V>& is, unsigned v)
        {
            split_free(ar, is, v);
        }
} }
const std::string Filename = "tmp.archive";
typedef boost::icl::discrete_interval<int> Interval;
typedef boost::icl::interval_set<int> IntervalSet;
#include <fstream>
#include <string>
int main()
{
    {
        std::ofstream f(Filename);
        boost::archive::binary_oarchive oa(f);
        IntervalSet s;
        s += Interval::closed(100, 200); 
        s += Interval::left_open(30,45);
        s += Interval::right_open(77, 78);
        oa << s;
    }
    {
        std::ifstream f(Filename);
        boost::archive::binary_iarchive ia(f);
        IntervalSet s;
        ia >> s;
        std::cout << "Deserialized: ";
        std::copy(s.begin(), s.end(), std::ostream_iterator<Interval>(std::cout, " "));
    }
}

打印:

Deserialized: (30,45] [77,78) [100,200]