śr., 6 mar 2019 o 17:39 Peter Dimov via Boost <boost@lists.boost.org> napisał(a):
Andrzej Krzemienski wrote:
I am interested in the latter ("Otherwise") case, so, going to emplace:
template<size_t I, class... A> constexpr variant_alternative_t<I, variant<T...>>& emplace( A&&... a );
- Requires: I < sizeof(T…).
Effects: Destroys the currently contained value, then initializes a new contained value as if using the expression Ti(std::forward<A>(a)…).
This doesn't mention any double buffering. No tricks, no "monostate". It reads as if the variant is left with no contained object whatsoever.
Yes, we mentioned that upthread. At minimum, I'll need to add Remarks that on exception, the variant is left in a valid but unspecified state.
Rigorously specifying the exact behavior of emplace will be rather verbose, and I'm not yet sure how to go about it.
There is a number of tricks to put back the variant to a non-empty state after a throw, and you may wish to reserve the right to change them in the future (and guarantee only that one of the Ts is stored with a valid but unspecified value). However, it looks like you also want to guarantee some smaller things: * If one of the types is `monostate` you guarantee that upon throw, the type stored is `monostate`. * If at least one type satisfies the noexcept requirements you guarantee that the size of variant<T...> is no more that the biggest of T plus the discriminator. Regards, Andrzej