Boost logo

Boost Users :

Subject: Re: [Boost-users] serialization: pointer reconstruction
From: Noah Roberts (roberts.noah_at_[hidden])
Date: 2010-01-27 15:45:25


In article <hjnbd6$7d8$1_at_[hidden]>, ramey_at_[hidden] says...
>
> I believe that what you want to do is already handled automatically
> by the serialization library. The only requirement is that struct B
> be serialized before struct C. The serialization library handles
> all the id management internally.

You're right, I don't know why I thought it necessary. However, in
bringing this into production code I realized that my example wasn't
completely similar. There's an important difference that I don't
understand why it's important. Struct C actually looks like so:

struct C
{
  A const* a;
};

In order to serialize C I needed to make the serialize member function
look like so:

template < typename Archive >
void serialize(Archive & ar, unsigned int const)
{
  A *& ptr = const_cast<A*&>(a);
  ar & a;
}

Simply attempting to archive the pointer to constant directly resulted
in bad things. Namely a compiler vomit about inability to
reinterpret_cast to a non-const **.

Is there a safer workaround?

>
> Robert Ramey
>
>
> Noah Roberts wrote:
> > A while back I asked about saving a pointer to an item in another
> > class that is stored as a direct instance variable (no pointer).
> > Here's a brief illustration:
> >
> > struct A
> > {
> > };
> >
> > struct B
> > {
> > A a;
> > };
> >
> > struct C
> > {
> > A * a; // points to a B::a.
> > };
> >
> > I have an idea how to store and restore these relationships but I'd
> > like to see if there are any improvement ideas and/or direction to
> > existing behavior I'm not seeing in the documentation.
> >
> > My idea is to first store B::a (which simply makes sense in my problem
> > anyway) and when I do this to call some custom support functions to
> > generate a unique ID for the object at that address and store it
> > first, then the rest of the data in A. This would appear in
> > A::serialize and the unique ID would be stored in the Archive (added
> > behavior) as a map from address to uid.
> >
> > Then when storing C I would request the unique ID for the address the
> > pointer stores and store it.
> >
> > On reading I read B::a first and it sort of reverses the process. The
> > uid is read and then A::serialize stores the uid and 'this' in the
> > archive map in a uid->address format. I then read the uid on reading
> > C::a and request the address from the archive using that value.
> >
> > I've already subclassed the Archive in order to pass around other load
> > information needed by classes that didn't have local copies, so that's
> > the easy part (though it wasn't a straight forward operation). The
> > question I have though is that since the pointer archiving already
> > must use some similar type of API, can I use it instead of rolling my
> > own and how would I do that?


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