It should be noted that variant2 DOES NOT PROVIDE A STRONG EXCEPTION SAFETY GUARANTEE. The never-empty guarantee has a certain negative effect of confusing people so that they are led to believe that they have strong exception safety. But they don't. even expert programmers in this forum expressed their surprise that changing from X to Y in variant
can get them a variant storing Z. Sometimes it is even trickier: X may be a container that currently stores 10 elements. You assign Y, and after the exception you get an X that stores zero elements. Because of these problems, the only reasonable thing to do is to follow the advice from Dave Abraham's article: https://www.boost.org/community/exception_safety.html To quote the relevant part, "If a component has many valid states, after an exception we have no idea what state the component is in; only that the state is valid. The options for recovery in this case are limited: either destruction or resetting the component to some known state before further use." If this principle is followed no-one will ever observe the valueless_by_exception state. This also applies to variant2. If this principle from Dave Abrahams is followed, no-one will ever benefit from
On Tue, Apr 2, 2019 at 9:28 AM Andrzej Krzemienski via Boost < boost@lists.boost.org> wrote: the
never-empty guarantee (but people will still pay the costs of providing it). You cannot do anything meaningful with variant that threw other than destroy or reset it. (But it is probably best to destroy it.) If objects are allowed to survive the stack unwinding, they should either offer a strong exception safety guarantee, or you have to have some very detailed knowledge of a given particular type how its state gets modified under exceptions, but this is usually very difficult and best left to experts.
The argument for a variant type that never ends up in a "valueless" state is not that it is wonderful to deal with objects that change state from X to Y, but that error recovery code is already difficult to write correctly, and while dealing with an object found in a state we didn't leave it in (basic exception safety guarantee) may be annoying, this is preferable than having to deal with objects that explode unless they're destroyed. It's not that programmers "want" to do something with the object other than destroying it, but 1) it is difficult to ensure that this can never ever happen and 2) the way it can be ensured is to sprinkle checks at random places (e.g. where variant asserts are triggered when during error recovery some code happens to touch an object but not destroy it), which is even worse.