
Niall Douglas wrote:
It so happens that the strong guarantee is unachievable with variant (without too much double buffering.) You can either have basic, or noexcept.
You surprise me, given this is a design capable of double buffering.
For a variant2<A, B>, where both A and B have throwing move constructors and assignment, surely if the variant has state A in buffer1, setting it to state B would use buffer2. If B throws during move, we simply don't change the currently selected buffer to buffer2. The variant's A state remains untouched i.e. strong guarantee.
I guess you haven't written out anywhere how and when the double buffering comes into play.
That is actually the one thing I have written, twice, once in the README and one in the Overview section of the documentation. :-) "To avoid going into a valueless-by-exception state, this implementation falls back to using double storage unless * one of the alternatives is the type monostate, * one of the alternatives has a nonthrowing default constructor, or * all the contained types are nothrow move constructible." So, yes, variant<A, B> will be double-buffered, but variant<monostate, A, B> and variant<int, A, B> won't be.