Boost logo

Boost Users :

Subject: Re: [Boost-users] serialization: pointer reconstruction
From: Robert Ramey (ramey_at_[hidden])
Date: 2010-01-27 17:01:25


Noah Roberts wrote:
> 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?

Currently in the TRAC database is an item which points out this problem.
Also someone else recently had a similar situation. I haven't had time
to give the scrutiny it deserves.

A simple workaround would be to just relace A const * with A *.

>
>>
>> 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