Serialization structure tree using boost :: serialization

I need to serialize libkdtree ++ in my program, tree structures are briefly described as follows:

struct _Node_base {
  _Node_base * _M_parent, *_M_left, * _M_right;

  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & _M_left & _M_right;
  }
}

template<typename V>
struct _Node : public _Node_base {
  typedef V value_type;
  value_type value;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar.register_type(static_cast<_Node*>(NULL));
    ar & boost::serialization::base_object<_Node_base>(*this);
    ar & value;
  }
}

struct Tree {
  _Node * root;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & root;
  }
}

This program reports a stream error. But from the "serailzed file", it lacks value fields for child root nodes. Thus, I think it is possible that BaseNode serializes the _M_left and _M_right pointer. However, since _Node_base has no idea about the type of the _Node value, it is therefore difficult to add "ar.register_type" to _Node_base.serialize ().

+3
source share
2 answers

The following solution for libkdtree ++ and boost :: serialization seems to work:

// KDTree::_Node
friend class boost::serialization::access;
template<class Archive>
//void serialize(Archive & ar, const unsigned int version)
void save(Archive & ar, const unsigned int version) const
{
  ar.register_type(static_cast< _Link_type>(NULL));
  ar & boost::serialization::base_object<_Node_base>(*this);
  _Link_type left = static_cast<_Link_type>(_M_left);
  _Link_type right = static_cast<_Link_type>(_M_right);
  ar & left & right;
  ar & _M_value;
}


template<class Archive>
void load(Archive & ar, const unsigned int version)
{
    ar.register_type(static_cast< _Link_type>(NULL));
    ar & boost::serialization::base_object<_Node_base>(*this);
    _Link_type left, right;
    ar & left & right;
    ar & _M_value;
    if (left) {
       left->_M_parent = this;
    } 
    if (right) {
       right->_M_parent = this;
    }
    _M_left = left;
    _M_right = right;
}

BOOST_SERIALIZATION_SPLIT_MEMBER()
0

pointer_conflict documentation state (sic):

    pointer_conflict,   // an attempt has been made to directly
                        // serialization::detail an object
                        // after having already serialzed the same
                        // object through a pointer.  Were this permited,
                        // it the archive load would result in the
                        // creation of an extra copy of the obect.

, , ptr BaseNode::serialize , *Node, Node::serialize. , base_object , ptr, , .

, parent ptr. , , ptrs, node. . BaseNode:

void fix (BaseNode* parent = 0)
{
    this->parent = parent;
    if (left != 0)
        left->fix (this);
    if (right != 0)
        right->fix (this);
}

root->fix ()

0

Source: https://habr.com/ru/post/1756128/


All Articles