2017-06-05 20:05 GMT+02:00 Niall Douglas via Boost
On Mon, Jun 5, 2017 at 7:57 AM, Peter Dimov via Boost
wrote: Gottlob Frege wrote:
Some days I'm like "man just accept empty, it would be a simple API", but then I think "it is stupid for variant
to be empty". Other days I think "just double buffer when necessary" (I assume that's your On 05/06/2017 15:23, Gottlob Frege via Boost wrote: direction
Peter?), but then I think "I don't want double-buffering variant
to go on/off based on whether I use MS std vs libc++ etc" and also "I don't want double buffering for cases that only happen in theory, not in practice".
That is my direction, yes. My variant uses double storage when (1) not all types have noexcept move constructors and (2) there isn't a noexcept default constructible type in the list.
So converting a Circle to a Triangle might result in a Rectangle, because Rectangle is the fallback? I'd rather have double buffering or valueless_by_exception. ie correctness or acknowledgement of error. Not silent incorrectness.
I hate with a passion any possibility of a variant changing its state without me explicitly telling it to do so. The only tolerable state a variant should ever choose on its own is empty/valueless.
I repeat my suggestion that for variant2:
1. If at least all types minus one have nothrow move construction, you get the strongest possible never empty never change guarantee.
2. If the user is dumb enough to supply more than one type with a throwing move constructor, they get the current C++ 17 variant valueless by exception semantics i.e. go valueless if changing state threw an exception and the previous state threw an exception on attempt to restore.
3. We thus never double storage.
4. And we never, EVER change state silently to something the user did not explicitly ask for.
I would recommend not mixing the design discussion of `variant2` with the
design considerations of `outcome`. `outcome` has its own design
constraints: it is natural to have only one type with a potentially
throwing move constructor. In contrast, `variant2