Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2002-07-02 11:40:08


Robert Ramey wrote:

> > The system is based on the fact that all components are saved and loaded
> > in exactly the same sequence. This will always be true unless an error
> > has been commited.
>
> I disagree here. Let's consider polymorphic class B and
>
> vector<B*> data;
>
> In order to correctly save this data you'd need to register *all* classes
> derived from B. As I say before, there two problems:
> 1. you have to repeat the registration for each place where you create
> archive object.
>
> true - but typically archives would be created in very few places.

Even 3 places is enough to create maintenance problems.

> 2. the code which creates archive objects might not know the list of *all*
> derived classes.
>
> at some level, code will know what is the most derived object created.

But how this information will be communicated to the code which saves/loads.

> this can be at a level much higher than the class that uses the polymorphic
> pointer. Its hard to discuss this without examining specific instances.

I think that "specific instances" would only have different names. Let me try.
class Path_estimation {}; // polymorphic
class Estimations {
    vector<Path_estimation*> path_estimations;
};

int main()
{
        Estimations e;
        for .....
                e.path_estimations.push_back(compute_estimation(.....)) ;
        oarchive a;
        a << e;
}

Here, only 'compute_estimation' knows the exact type of Path_estimation
derived class which it creates and returns. But it has no idea that "main"
saves anything. So, how "main" can register classes derived from
Path_estimation?

> I understand that it is inconvenient to to sometimes have to "register"
> classes not otherwise seen by the archive. The decision to do it this way
> was a pragmatic one based on the following considerations.
>
> a) type_id(..).name is not guarenteed to be portable. In fact each
> compiler I looked at had a dfferent way of rendering the name of a class.
> It wasn't even always obvious how to do it. This would mean that the
> archive would have to do one of two things
>
> i) know about how type_id(...).name is handled by all other compilers that
> might create archives and maintain code that does the translation to that
> used by the compiler loading the archive.
>
> or
>
> ii) write a routine to render the class name in some canonical form. This
> would mean doing some sort of "registration" for ALL classes used not
> just some of those used by polymorphic pointers
>
> Of course if there is a third alternative, I would be interested in
> hearing about it. But given these two alternatives, the choice for me is
> easy as I think it would be for most boost members. .

I believe that without type_id we just cannot guarantee that the system will
work for one application on one toolset. So, for me it's better to use typeid
now. Later, someone might write a portable typeid. Indeed, David Abrahams has
challanged boosters to write it.

> b) the need to "register" a class in a rare occurence in practical
> problems. The map demo doesn't require it because classes are "seen" by the
> archive before the polymorphic collection is used. This is a common
> (though admitedly not a universal) situation.
>
> c) the fact that this situation is detected when the archive is created -
> even in a release build - Guarentees that no unreadable archives will be
> released.

Not sure. If you have two applications you can very well produce an archive
that the other one cannot read.

> By the way, the first version used typedef in the archive. The problems
> that this engendered were pointed out by the usual suspects - astute boost
> members. It was in addressing this objections that I came to the current
> system. I believe it is the best solution and inspite of this minor
> inconvenience quite a good one
>
> So, how do you propose to solve this problems, and why the solution can't
> be incorporated in the library?
>
> > > Also, as I understand, if a class never seen by the serialization code
> > > is written, then type_info_extended::find will return 0 and assert
> > > will fail. Prior versions had a way to register a class. I'd like to
> > > have that way again in the library.
> >
> > writing a NULL pointer of the derived class to the archive is equivalent
> > to "registering" the class in the previous system.
>
> Yea, except that this method is not explicit and has the disadvantages I've
> explained above.
>
> would you be satisifed if the following if something like the following
> were added back in?
>
> template<class T>
> serialization::basic_oarchive::register()
> {
> *this << static_cast<T *>(NULL);
> }
> template<class T>
> serialization::basic_iarchive::register()
> {
> T *t
> *this >> t;
> assert(NULL == t)
> }
>
> This would permit one to use
>
> save(...)
> ar.register<class>()
>
> rather than just
>
> save(...)
> *this << static_cast<T *>(NULL);
>
> Personally I don't think it adds anything. It might be more explicit
> though. In my view this is a very minor question of esthetics.

That would be much better. How can somebody, looking at the code, realize
that storing 0 is used to register a class?

BTW, Robert, it is really hard to read messages without quoting. If you've
got problems with replying email, maybe you can try the news interface?
(www.boost.org contains pointer to it)

- Volodya


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk