Le 05/06/2017 à 13:57, Peter Dimov via Boost a écrit :
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 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.
I think that in practice few variants will hit the double case, as it's rare to have variant
without a scalar alternative, although who knows.
For variant
specifically, when going from libstdc++ to MS STL the difference is that sizeof(variant) changes, but it changes for std::variant, too. Obviously, double storage can never be as good as single storage, but I view this as an acceptable compromise. You can guarantee single storage by putting a nothrow default constructible type in the list of alternatives. Alternatively, we could as well add a phantom type that says, please, use double buffering if absolutely needed.
- I think std::expected should always throw something deriving from std::exception. So if E derives from std::exception, we can throw it. If E is exception_ptr we can (re)throw it. If E is error_code/system_error/etc we can figure out what to throw. If E is user-type, then we wrap it in bad_expected or whatever.
My suggested expected<> just calls `throw_on_unexpected(e)` unqualified (it's a customization point.) There are overloads for std::error_code and std::exception_ptr and the fallback default is to throw bad_expected_access<E>.
The current proposal (not necessary accepted) throw always bad_expected_access. If we can throw different exceptions, I believe that we should have as well a type_trait that gives the exception thrown by an error. This could be useful for generic code. I have not a concrete use case in mind yet. Vicente