Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-08-29 17:07:03


On Wednesday 29 August 2001 04:06, you wrote:
> From: "Douglas Gregor" <gregod_at_[hidden]>
> [... on optional ...]
>
> > I was recently working on a variant type that was intended to be created
> > on the stack. I believe it is possible to do, though it isn't trivial :).
>
> If I understand intention behind 'variant' correctly (I think of 'variant'
> as a safe union that allows types with constructors and destructors) then I
> agree that it should be doable, but it is somewhat tricky to get it right:
> - alignment
> - exception safety
> - safe/unsafe vswitch

Alignment & exception safety are somewhat at odds. For instance, if I have a
variants a and b and I want to swap them, it is tough (maybe impossible?) to
do this in an exception-safe manner for pathological types. Safe vswitch is
the easy part :).

> Now, if understand 'variant' correctly, then it seems to me that 'optional'
> could be implemented something like this (without run-time overhead on an
> ideal, but not "magical", compiler):
>
> template<class t>
> struct optional
> {
> ...
> private:
> variant<t,void> v;
> };

Yes, though replace "void" with a real (but useless) type, like:
struct unused {};

> 'optional' could also be implemented using 'any', but this would imply
> considerable run-time overhead.

Yes.

> I think that 'variant', 'optional', 'any' and smart pointers all have
> similarities but also significant intentional differences.
>
> NOTE: The following reflects my current thinking - it is more than likely
> that I have misunderstood some of the concepts.
>
> [I would rather arrange these into a nice table, but text based e-mail just
> doesn't cut it.]
>
> Intent:
> - optional: signaling errors/uncomputable results, lazy initialization
> - variant: safe union ???
> - any: typeless programming (it seems like a "boxed value")
> - smart pointer: avoiding resource leaks/automatic finalization, exception
> safety

variant: discriminated union that also allows non-trivial
constructors/destructors.

> Initialization:
> - optional: lazy
> - variant: ???
> - any: lazy
> - smart pointer: strict (or this is how I see the matter)
>
> Should 'variant' support lazy initialization? Parhaps variant<> should
> support being left unitialized only if 'void' is one of the variant types.

variant uses lazy initialization, though I can't say I like it much.

> What about 'any'? Should it be 'any_or_none' or 'optional_any'?

The name "any" seems reasonable...

> Morphology:
> - optional: monomorphic
> - variant: bounded polymorphic ???
> - any: unbounded polymorphic / typeless
> - smart pointer: subtype polymorphic (typically)

Looks good.

> Copy semantics:
> - optional: value
> - variant: value
> - any: value
> - smart pointer: reference, destructive copy or value (clone)

Looks good. Not sure I agree with "destructive copy" or "value". I would just
say that smart pointers have reference semantics, but for objects with
managed lifetimes.

> The smart pointer concept seems rather overloaded.
>
> Syntax / operations:
> - optional: pointer
> - variant: vswitch, empty, cast, type ???
> - any: empty, cast, type
> - smart pointer: pointer
>
> I think that all of the above concepts should be further refined. For
> instance:
> - 'any' could probably make use of the 'vswitch' syntax.

Yes. Both 'any' and 'variant' would use the same vswitch statement (or
perhaps 'inspect', like Simula had...). The only difference is that variant
can be sure that all possible types are handled by the switch.

> - 'variant<T,void>' seems very close to 'optional<T>'.

It is very close semantically.

> - 'variant' and 'any' might or might not make use of some pointer syntax.

Pointer syntax doesn't really make sense for variant or any, because there is
no fixed return type for either. For optional and smart pointer, there is
only one possible type. This I think justifies the syntactic differences.

> Assuming that optional and variant make it into Boost, I think that Boost
> should have documentation which describes the differences between these
> concepts and should perhaps include a decision tree for choosing the best
> alternative.

I agree fully. It seems that Boost is getting more interrelated libraries,
and at some point unifying documentation may be needed to guide users through
the Boost libraries. Essentially, it would explain common Boost library
interactions, e.g., using bind to make a function call into a separate thread
using the Threads library.

        Doug


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