On 14/07/2017 06:09, Emil Dotchevski wrote:
If std::error_code is sufficient, put your money where your mouth is and go back to outcome v1 where the only choices were std::error_code and std::exception_ptr. But the reality is that std::error_code is not sufficient (perhaps not due to its own deficiencies); in practice you do need to be able to transport more or less arbitrary error types.
I think the issue is that while std::error_code is sufficient to convey an error *code*, it is not sufficient to convey an error *context*. Outcome v1 solved this by standardising on a slightly-larger type that conveyed a specific small set of additional data, which was deemed good enough for most uses -- but there's still a bit of sacrifice involved there since it would be too much for some cases and too little for others, combined with the separated storage causing it to sometimes go away unexpectedly. I mentioned in a discussion thread at the time that it might be useful to consider having multiple user-defined derived subtypes of std::error_code (or one standard templated one) to add additional context state, similar to how std::exception is subclassed to add additional state to that. Though this has some downsides as well, mainly requirement to not pass by value (unless you want to slice off the extra data) and possible introduction of memory allocations (eg. if std::string were in the payload), which also discourages pass-by-value. Outcome v2 appears to have chosen a different path, where you mostly still use unadorned std::error_code (although since it's templated it's possible you could still do the above) but you also get an extra arbitrary payload pointer *or* an exception_ptr (where then presumably your extra payload is carried in a particular exception subclass). I'm still a bit on the fence about that latter option; exception_ptrs are a bit of a pain to extract useful information from. Or perhaps I'm just misinterpreting something; the docs are still incomplete after all.