From: Fernando Cacciola (fcacciola_at_[hidden])
Date: 2002-08-09 15:26:20
----- Original Message -----
From: "Douglas Gregor" <gregod_at_[hidden]>
Sent: Friday, August 09, 2002 3:27 PM
Subject: Re: [boost] Re: Empty boost::variant semantics (was
> void foo(T& t, U& u)
> variant<T, U> v(t);
> v = u;
> Prior to the assignment "v = u", we have memory inside 'v' that stores a
> of type 'T'. After the assignment "v = u", that same memory inside 'v'
> store a value of type 'U'. Because the U needs to occupy the same space as
> the T does now, the T must be destructed before the U is constructed.
> However, U's construction can throw so we need to save the value of T.
Only if you want to leave v either empty or defined.
I agree that empty variants should be avoided as much as possible.
But as I said in a previous message, I don't think that variant should
struggle so badly to keep itself consistent when it is feed with types which
If such consistency could be achieved more or less nicely; I'd go for it,
but the more we think of it the more we realize how difficult it is, not in
terms of intelectual excercise, but in terms of space and/or time overhead.
To reiterate my position:
If the user-defined copy-ctor throws, AND variant does NOTHING, not even
resetting 'v' to empty before the assignment, the variant lvalue will be
left undefined. Not empty, just plain inconsistent.
This sounds terrifying, but it isn't, because a user defined type whose
copy-constructor throws will most likely define an assignment operator which
also throws, so the situation won't be any worse than working with this
broken-type (as David called it) directly.
IMO, since variant<> is essentially a compound type, exception-free
assignment should be guaranteed by the types it contains, not by itself. We
shouldn't except it to do more than whatever the types themselves do.
Besides, it will always be possible for a user to wrap offending types.
Also, the current implementation uses the copy-ctor in place of the
assignment operator. This shouldn't be a problem, though, but unless
*really* necessary, I wouldn't bypass T's operator=.
void foo(T& t, U& u)
variant<T, U> v(t);
v = u;
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk