Subject: Re: [boost] Outcome v2
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-07-11 23:45:29
On 12/07/2017 02:18, Niall Douglas wrote:
> On 11/07/2017 12:53, Peter Dimov wrote:
>> I would make outcome<> reuse 100% of result<>'s implementation, by
>> stealing another page from your playbook:
>> class extended_error_code
>> std::error_code e_;
>> std::exception_ptr x_;
>> template<class T> using outcome = result<T, extended_error_code>;
> That may well happen yet. What held me back was that the universality of
> EC = error_code is very important in order to use TRY effectively.
> That's what led to the split design you see today, so you're basically
> exchanging some purity in the design for ease of programming. TRY is
> such a boon for not typing boilerplate.
struct extended_error_code : public std::error_code
template<class T> using outcome = result<T, extended_error_code>;
This allows generic code to treat EC exactly as a std::error_code (both
for method calls and to slice off the exception if they wish).
Having said that, this would basically render it impossible to have
value + exception *without* an error_code. You could mitigate that by
defining a default "there is an exception" error_code (which you might
be doing anyway), though it feels a little weird. (Then again, it's
probably worse to leave the std::error_code default-constructed.)
> A majority of peer review feedback didn't see the need for variant
> storage. Eliminating it very significantly reduces the complexity of the
> implementation, it's a big gain. I was able to SFINAE all the
> constructors because of the compile time budget released by eliminating
> the variant storage.
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.