Boost ICL与Boost序列化的结合

时间:2014-06-02 22:23:11

标签: c++ serialization boost

我正在尝试使用Boost Serialization库来存档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)

1 个答案:

答案 0 :(得分:0)

iterative_size()不会返回lvalue,这是必需的。无论如何,你都不能有用地反序列化派生属性(与向量没有&#39; t(de)序列化size()成员结果的方式非常相似。而是序列化所有数据,{{1碰巧最终会变得相同。

另见

  

如果没有这样的默认构造函数,则必须覆盖函数模板size()load_construct_data。这是一个简单的例子

来自docs

在对象实例仅从(非默认)构造函数参数初始化的情况下可能有用。

更新以下是演示实施: Live On Coliru

save_construct_data

打印:

#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, " "));
    }
}