c++ - Boost ICL 和 Boost 序列化的结合

标签 c++ serialization boost

我正在尝试使用 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,操作系统 - Xubuntu 3.11)

最佳答案

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

也看看

If there is no such default constructor, the function templates load_construct_data and perhaps save_construct_data will have to be overridden. Here is a simple example

来自docs

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

更新 这是一个演示实现: 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] 

关于c++ - Boost ICL 和 Boost 序列化的结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24004243/

相关文章:

C++ 析构函数(附代码示例)

iphone - 在 iOS 中实现搜索历史功能

c++ - 我如何在 boost::regex 中使用反向引用

c++ - Segmentation fault (core dumped) - 无法修复错误

java - 在 MVC 中从 WCF 服务反序列化 Json 时出错

c++ - 使用 boost::bind 输出作为数组下标

C++ 搞砸了 : optional argument forced to be mandatory

c++ - boost 信号 : Expose signal itself or connect/disconnect methods in class interface?

c++ - STL std::remove_if 编译器失败

python - 为什么json序列化比Python中的yaml序列化快那么多?