Boost logo

Boost :

From: ERICSSON,JOHAN (A-Sonoma,ex1) (johan_ericsson_at_[hidden])
Date: 2001-11-19 12:17:12


> It's sometimes very useful to defer the initialization;
default-constructing
> a variant<> is way more efficient than copying a dummy value; and when you
> need to construct a variant<> from a persistent store (using f.ex. an
> appripriately crafted operator>>) it needs to be default-constructible.

I wrote my own version of the 'variant' class, calling it poly_ptr just to
try it out. It is a really neat technique that these classes (variant, any)
use, where they create an inheritance hierarchy to add information to user
defined types. This removes the need for the UDT to have the clone() method.

There is a trade-off however...

Given these two methods to implement a poly_ptr<> (or variant) class.
1. Require the supplier of the UDT to provide a clone() method
2. Use the methods in the 'variant', and 'any' class to supplement the UDT
with a clone method

We've already spoken of the advantages of method 2. The disadvantage is that
method 2 can not be used to attach to a type that is already being referred
to through a pointer, or reference, to its parent.

For instance,

variant<parent> f(parent& p)
{
        // Create a copy of the 'parent'
}

This doesn't appear to be possible using method 2. This would work with
method 1, as the clone() method is accessible through the parent.

If the signature of the method was:
void f(variant<parent>& p)

Then method 2 would work as well as method 1.

This might not be a big deal... just pass around the wrapped type, not just
the contained type.

My only real concern is with the serialization. I'm using MFC's method (ugh)
of serializing object hiearchies. While their method is littered with ugly
macros, etc, I am pretty sure that their method is fundamentally the same as
any other serialization method.

MFC's deserialization provides me with a pointer to the parent type after it
is deserialized. So, it won't be possible to use their deserialization using
method 2. It can't attach, even if the parent has a clone() method. This can
probably be fixed by using a serialization technique that knows about the
'variant' type. If the deserilization provided me with the 'variant' type,
then there would be no problem.

Anyways, I like the 'variant' method much better than the clone() method
everywhere. This just seems to be one place where it is less flexible than
the clone() method.

> There's no reason to do if(p.get()) p->DoSomething(). If you don't ever
> create empty variants, p->DoSomething() is enough (it will BOOST_ASSERT -
in
> its final form, that is.)

Just the same reason that developers prefer references to pointers. Pointers
don't ever have to be NULL... but they could be.

> > Also, not sure if variant is the right name. When I think 'variant', I
think
>> of the 'any' class. Not sure if the names distinguish where their uses
>> differ.

> variant<T> is a 'bounded-by-inheritance' variant, as opposed to any (it's
an
> unbounded variant) or to a discriminated union (it's bounded by a
concrete,
> finite set of types.)

> variant<void> is (very) similar to any.

That is interesting. The 'variant' can be used to simulate an 'any' class.

Is there a name to describe the idiom common to both the 'any' and the
'variant' class?

Johan


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