
From: "Fredrik Blomqvist"
Peter Dimov wrote: [snip]
FWIW, in my own library I do, indeed, have a special case code for serializing an unmodified shared_ptr, for two reasons. First, this shows that the library is flexible enough. Second, even if we modify boost::shared_ptr to be boost::serialization-friendly, we won't be able to patch std::tr1::shared_ptr.
Interesting to hear that this approach has been used by more people! I also believe being able to handle almost any smart-ptr would be a big plus. Some monolitic frameworks "force" you to used their smart-ptrs for example... Do you use some kind of general registration mechanism for the classes that needs this treatment btw?
I use a very simple manual registration scheme. Something like register_read<xml_reader, my_class>(); register_write<xml_writer, my_class>(); register_conversion<my_class, my_base>();
the general idea is that they keep a map< shared_ptr<void>, int > on writing, mapping every shared_ptr ownership group to a pointer id, and a corresponding map< int, shared_ptr<void> > on reading, for the reverse transformation.
The main problem for implementing a non-intrusive serialize() for shared_ptr is that these pointer maps need to be held in the archive, which requires either archive modification, or a general "extra state" support in all archives.
Hmm, in my implementation I _don't_ save anything but the raw-ptrs to the archive. Only at load-time is a temporary map maintained that intercepts loading of smart_ptrs and "seeds" them starting from the first one.
It's pretty much the same either way (assuming polymorphic classes and dynamic_cast<void*>(p)). The only case that comes to mind where the two approaches differ is when you save a shared_ptr<T>, then a shared_ptr<void> that shares ownership with it but points to a subobject. But this isn't a very important case in practice. I used a shared_ptr-specific map because I haven't even tried to handle raw pointers (by design) since a raw pointer can have so many meanings that - I decided - there was no reasonable default.