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.
Could we have instead then the following more elemental variants: 1. single_buffered_variant<...>: Never enters a trap state (where valueless_on_exception() = true). Always single buffered. Requires at least one state to have a nothrow default constructor, or all states to have nothrow move constructors. 2. double_buffered_variant<...>: Never enters a trap state (where valueless_on_exception() = true). Always double buffered. Always implements the strong exception guarantee. I would prefer this design because Boost users are more than capable of writing a std::conditional_t<> which chooses what the variant implementation is, based on input types e.g. template<class... Args> using mylocalvariant = std::conditional_t<is_trivially_copyable_for_all<Args...>, single_buffered_variant<Args...>, double_buffered_variant<Args...>>; I personally don't think that you need to choose a hard coded mix of single and double buffered variant. Rather, let the Boost user choose the mix. (But if you're dead set on there being a boost::variant2::variant<...>, let it be a template alias to your current variant mix) Niall