Boost logo

Boost :

From: Eric Friedman (ebf_at_[hidden])
Date: 2003-10-26 21:58:12


Brian McNamara wrote:
> On Sun, Oct 26, 2003 at 01:24:14PM -0800, Jaap Suter wrote:
>
>> boost::variant<foo, bar> v;
>> bar b;
>> v = b; // copy constructs b into v, first destroying the old foo.
>
>
> The word "first" above bothers me.
>
> I can see why, in your particular application, it is useful to "first
> destroy the old value, then construct the new value". However I think
> this implies that variants give up the "strong" exception guarantee.
> (Actually I have lost track of if variant currently gives the strong
> guarantee; if not, my point is moot.)

Variant has not had a strong exception-safety guarantee for some time
now. However, *strong* exception-safety is not what is particularly
relevant to the current discussion...

[snip]
>>Notice that my suggestion implies that it would become possible to put
>>non-copy-constructible objects into boost::variant. Perhaps, if the above
>
>
> This does seem to be a useful capability. The ordering is an issue,
> though (e.g. is it "first construct the new value, then destroy the old
> value" or vice versa). This directly affects a lot of the recent
> discussion about variant's implementation, I think.

Since variant does not store its content on the heap, this
destroy-first-then-XXX (copy, construct, etc.) is what must be used.
Indeed, inplace construction would be a generalization of the current
behavior (i.e., destroy-first-then-copy). In other words, the current
behavior could in principle be implemented *in terms of* inplace
construction...

>>suggestion is considered too esoteric, somebody can think of a scheme that
>>allows me to do the above, without using dynamic memory allocations (the
>>whole reason I'm using variant in the first place).
>
>
> Do all of your state types have nothrow constructors? If the call to
> v.construct<T>(args)
> is calling a nothrow constructor, then the "destroy, then create"
> ordering can still preserve the strong guarantee, it seems.

Variant provides the basic guarantee for assignment lhs = rhs by copying
the content of lhs onto the heap before its destruction. Then the
content of rhs is copied to the storage of lhs. In the event of success,
the backup is destroyed; in the event of an exception, the lhs variant
stores a pointer to the backup and "redirects" all visitation requests
accordingly.

So from an exception-safety point of view, it really doesn't matter too
much whether Jaap's state types have nothrow constructors or not. The
only difference will be that variant will avoid heap backup if any of
the types are nothrow default-constructible. (Or if all of the types are
nothrow copy-constructible, but that doesn't apply in this case.)

> There was a lot of discussion about variant and issues related to
this > a month or two ago, but I lost track of where things finally
ended up.

It will all be described in the final documentation.

  - Eric


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