From: Emil Dotchevski (emil_at_[hidden])
Date: 2008-08-04 14:48:45
On Mon, Aug 4, 2008 at 7:00 AM, Mathias Gaunard
> Emil Dotchevski wrote:
>>>> Do I read correctly that in an attempt to assign one variant object to
>>>> another, the left-hand object _might_ silently change its type?
>>> If an exception is thrown during assignment to a boost::variant<T0, T1,
>>> ...>, and one of the Ti is nothrow default-constructible, then the
>>> boost::variant will end up with a default-constructed value of one of those
>>> Ti. So even if the type happens already to be that Ti, the value will still
>>> change to the default value.
>> I have 3 variants of values, let's call them V0, V1 and V2. V0 values
>> are of type std::string, and V1 and V2 values are of type float.
>> However, boost::variant<std::string,float,float> is illegal;
> Then you should use tags, and not ugly hacks.
> Variant can be implemented in three (four?) different techniques
> (temporary heap backup, nothrow copy or move, nothrow default constructor).
> Only the last one (which is, unfortunately, the one invoked by your
> code), does not satisfy strong exception-safety. It's fairly funny how
> an optimization diminishes the safety of variant.
In my opinion the tradeoffs of basic exception guarantee in this case
are bigger than usual: the behavior it brings is very similar to an
object changing its type. These semantics are not compatible with the
usual semantics of operator=.
I understand that there are use cases where it is unreasonable to pay
the price of strong exception guarantee, but those cases can be
supported with a separate operation with a name that hints about the
unusual, possibly type-changing semantics.
Also, I am not necessarily advocating strong exception guarantee. I
would be fine if the semantics of operator= were such that it may
leave the object in a particular unusual state. The problem is that as
it is now, it may leave the object in a seemingly OK state.
Reverge Studios, Inc.