Andrzej Krzemienski wrote:
Some other thoughts:
When valueless is required as the first type, it also implies that the default constructor of variant puts it into valueless state, which some might find useful, but others inferior to std::variant. Would it be possible to also assign a special meaning to putting `valueless` at the end, which would assign semantics of std::variant?
`valueless` is proving to be a nuisance. I have for instance expected<T, E...> using variant<T, E...> under the hood. But this means that expected<valueless, E...> falls into the variant special case and it really shouldn't. So either I ignore this or would have to replace valueless internally with something else. So, yes, I did consider putting it at the end instead. But then it won't default construct to valueless, and you may actually want that. So we're going into variant<monostate, T..., valueless> then, which isn't what I'd call elegant. Maybe the right thing to do is just drop valueless and point people to std::variant if they need it. My ambition was to produce a superset of std::variant, but this may not be the right choice design-wise.
Maybe the choice how you want to implement the assignment should be explicitly controlled by the users (in form of a policy)? You could still provide the defaults based on properties of the types, but it looks to me sometimes people might want to override the defaults. For instance, we have seen examples where I want strong guarantee on assignment even when T does not offer one.
You use emplace then, or move assignment. Or swap, although I need to double-check whether it does what it needs to do in all the various cases.