
Niall Douglas wrote:
1b. make them default-construct to `make_error_code( outcome::errc::uninitialized_result )`.
I am not keen on magic constants in an errored state. I am also not keen on overloading the errored state with alternative meaning. The errored state is for indicating an end user operation failed somehow, not for detecting logic errors in user code.
This is precisely why I added a formal empty state, and default initialised to that. Because it causes behaviour different to valued or errored, it **very** effectively traps logic errors during code development. On **many** occasions it has successfully illuminated poorly thought through code that I have written by bringing to my attention - early and very obviously - that someone was very wrong. I am absolutely convinced it is a great design choice.
OK, fair enough. I don't think that the benefits of having a singular state outweigh its disadvantages, but to each his own.
I'd therefore be happier with default construction giving uninitialised contents, or a default constructed T or E. No overloading state of E.
result and outcome have no E. I'm not talking about E or expected<T, E> here. I'm talking specifically about result<T> and outcome<T>. That is, I'm trying to answer the question "Under the assumption that expected<T, E> doesn't exist, what should the default constructor of result<T> do?" Default constructing to an std::error_code of 0 is kind of stupid because "The operation failed: The operation succeeded", although one might, I suppose, make an argument in favor of constructing into a stupid state precisely because it's stupid.