
Mere moments ago, quoth I:
If you're going to maintain strict no-value-plus-error semantics then union/variant storage makes sense, as otherwise you're wasting memory. I'm not sure why this would increase complexity.
Although of course unions can be problematic for T with non-trivial copy constructors (and for exception_ptr, which also has a non-trivial copy constructor). A proper variant implementation should take care of that for you, though this didn't help you in Outcome v1 since you were rolling your own variant implementation. Perhaps this is what you were referring to? If you're using struct { T; EC } storage, what do you do with non-default-constructible T when constructed with an error code only? Leaving it unconstructed seems like the only reasonable solution, but this then either requires mucking about with constructors and destructors in annoying fashions or using std::aligned_storage rather than embedding T directly (which still requires mucking about with constructors and destructors). Using a variant just seems like the simpler way to go for this case.