Boost logo

Boost Users :

From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2006-09-16 15:30:42


Hello again, lots of talking to each other today :)

----- Mensaje original -----
De: Robert Ramey <ramey_at_[hidden]>
Fecha: Sábado, Septiembre 16, 2006 8:03 pm
Asunto: Re: [Boost-users] [serialization] Purpose of load_construct_data
(was: Re: Library Interface Design)

> JOAQUIN LOPEZ MU?Z wrote:
[...]
> > http://boost.org/libs/serialization/doc/
> > serialization.html#constructors
> > where my_class serializes my_class::m *both* at
> > my_class::serialize *and* my_class::(load|save)_construct_data.
> > If the analysis I develop in my previous post is correct
> > (is it?) this leads to my_class::m being serialized *twice*
> > when a pointer to my_class is saved. Maybe it would sufice
> > to rewrite this part of the documentation with a more
> > sensible example like the one at test_non_default_ctor.cpp.
> > What do you think?
>
> I agree. The fact that the example uses a member variable confuses
> the issue. I'll amend the documentation accordingly.

Thank you!

> However, the current example does illustrate a case where it
> seems impossible to avoid serializing a member twice. One
> could leave it in the load_construct_data, and eliminate it from
> the serialization code - but then this would work only if the
> object was serialized via a pointer. If it were my program I would
> say hmmmm - I'm really confusing the role of the variable m - If
> its to be initialzed at construction - it shouldn't be messed with
> by serialization or operator= etc. If its realy part of the objects
> dynamic state - then it shouldn't be required at construction time.

Well, I think the apparent puzzle stems from the incorrect
assumption (IMHO) that a given member must be either part of the
construction info or dynamic state --in many cases, it can be
*both*, which is precisely what happens with my_class.

I'd appreciate if you can consider this extension proposal that
would allow for one-phase serialization while keeping the
statu quo --maybe we can have our cake and eat it too :)

Augment the serialization interface with a pair of new
user-overridable function like this:

  template<typename Archive, class T>
  inline void construct_from_archive(
    Archive & ar, T * t, const unsigned int file_version)
  {
    // default implementation
    load_construct_data(ar,t,file_version);
    ar>>*t;
  }

  template<typename Archive, class T>
  inline void construct_to_archive( // OK, the name is ugly
    Archive & ar, const T * t, const unsigned int file_version)
  {
    // default implementation
    save_construct_data(ar,t,file_version);
    ar<<*t;
  }

and use it when serializating T through a pointer. Now,
if we return to the case of my_class, where my_class::m is
both used at construction them and serialized as part of
my_class::serialize, we can handle all situations as follows:

  // as in your example
  template<class Archive>
  inline void save_construct_data(
  Archive & ar, const my_class * t, const unsigned int)
  {
    ar << t->member;
  }

  // as in your example
  template<class Archive>
  inline void load_construct_data
  (
    Archive & ar, my_class * t, const unsigned int)
  {
    int m;
    ar >> m;
    ::new(t)my_class(m);
  }

  // this is new
  template<class Archive>
  inline void construct_to_archive(
  Archive & ar, const my_class * t, const unsigned int fv)
  {
    save_construct_data(ar,t,fv); // avoid m being saved twice
  }

  // this is new
  template<class Archive>
  inline void construct_from_archive(
  Archive & ar, my_class * t, const unsigned int fv)
  {
    load_construct_data(ar,t,fv); // avoid m being loaded twice
  }

My proposal basically amounts to adding a new customization
point to the existing protocol for serialization of pointers.
It has the following advantages:

* You don't break anything (it's a pure extension).
* It addresses a concern (one-phase serialization) that is
  conceptually different to the concerned addressed by
  (load|save)_construct_data (serializing non default-
  constructible objects), and does it so in an orthogonal
  manner.
* It lets you solve the problem of members being both
  part of construction info and dynamic state, as I've
  (hopefully) just shown .

How do you like this?

> Anyway, I'll alter my example to make the variable in question
> "const" and remove it from serialization which is a better
> of example of the real cases where this can come up.
>
> Robert Ramey

Best,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net