Boost logo

Boost :

From: Itay Maman (itay_maman_at_[hidden])
Date: 2002-08-09 03:03:42


"Eric Friedman" <ebf_at_[hidden]> wrote in message
news:001c01c23f28$87654d40$a600a8c0_at_eric...
> OK, let me summarize variant's behavior as currently implemented in the
> sandbox:
>
> On default construction, variant<T1, T2, ... , TN> default constructs
> T1. If T1's default construction throws, variant is never constructed,
> and so there is no problem.
>
> On copy construction from a non-empty variant, variant copies the given
> variant's held value. Again, if the copy throws, variant is never
> constructed, and so there is no problem.
>
> The difficulty comes with variant assign. On assign from a non-empty
> variant, *this clears itself (i.e. makes itself empty) and then copies
> the given variant's held value. If the copy throws, we now have a
> problem, as *this is now an empty variant.
>
>
This is generally very good. Three comments:
i) Variant should clear itself only *after* its assigned value's copy c'tor
throws, since there is no guaranteed that this c'tor is strongly exception
safe.
ii) assignment should be optimized for the case where the two varaints are
holding incomplete values:
    variant<incomplete<A>, B, C> v1;
    varriant<incomplete<X>, Y, Z> v2;

    v1 = v2; // incomplete<A> = incomplete<X> can be carried in safely

iii) [Given (ii)] I think we should offer an alternative for users who want
to trade speed for saftey, i.e:
    typedef safe_variant<A,B,C> var_t_1;
    typedef variant<incomplete<A>, incomplete<B>, incomplete<C> > var_t_2;

   // var_t_1 and var_t_2 are identical

The second item (ii) has been suggested before (by Doug), but we decided to
put it somewhere on the bottom of the list, since (at that time) it was
nothing more than an optimization. Now, it offers attractive safety
implications.

[snip]
> Now to answer your question as to what expressions are well-defined for
> an empty variant, var1:
>
> var1.empty(); // returns true
> var1.clear(); // essentially a no-op, as var1 is already empty
> var1.which(); // returns -1
> var1.type(); // returns typeid(void)
[snip]
> 1) Should variant::clear() become part of variant's public interface?
> That is, is the empty-variant concept somehow _useful_, or is it just an
> unfortunate necessary consequence of not having the strong guarantee?
>
> 2) Is it OK to leave visitation of an empty variant undefined, or should
> it be well-defined to throw some particular kind of exception?

I agree with Doug on these issues. An empty variant should support as few
operations as possible.

--
Itay Maman
    itay_maman@_yahoo_.com
    maman_at_il._ibm_.com
This message expresses my personal opinion.

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