Andrzej Krzemienski wrote:
For instance, the variant's move assignment will sometimes use T's move assignment rather than move constructor when changing the variant's type, as in the following example:
Interesting. Since the destructors and the move assignments are trivial, this variant has a pseudo-trivial move constructor, that is, it does the equivalent of memcpy. This however doesn't quite match the specification. I need to look into the latest changes to std::variant to see how it handles triviality in this case.
Describe the algorithm for achieving the [strong] guarantee.
It so happens that the strong guarantee is unachievable with variant (without too much double buffering.) You can either have basic, or noexcept. If all contained types have noexcept move constructors and noexcept move assignments, the move assignment of variant is noexcept. If all types have noexcept move constructors but not all have noexcept move assignments (this can be the case for f.ex. std::vector with a not-always-equal allocator), variant's move assignment is only as strong as the move assignments of the contained types, but emplace is noexcept. If not all types have noexcept move constructors, I don't know of a good way to achieve the strong guarantee.