Boost logo

Boost :

Subject: Re: [boost] [outcome] High level summary of review feedback accepted so far
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-06-02 00:06:03

On 2/06/2017 06:33, Niall Douglas wrote:
> On 01/06/2017 00:35, Gavin Lambert wrote:
>> On 1/06/2017 08:17, Niall Douglas wrote:
>>> The programmer, when working with outcome<T>, knows that calling
>>> .exception() will return the exact same exception as would be thrown
>>> when calling .value(), thus saving wrapping .value() in a try...catch
>>> just to capture the exception_ptr emitted.
>> Except empty. value() throws that as an exception. exception() also
>> throws that as an exception (not returning it), which means that the
>> programmer can't make that assumption you just claimed.
>> Maybe that's what you want (as it leads very quickly to empty ==
>> std::terminate), but it's not consistent with use of empty as a success
>> return as you've suggested in a few places.
> Empty is supposed to have the severest, most abnormal default actions.

But it means that in a noexcept method, it's unsafe to call exception()
without a try-catch, even though it would be safe to call in any case
other than empty. And it means that exception() doesn't return the
exception that would be thrown by value() in that case either.

Maybe the answer is "so check for empty first!" but that seems like
clutter if you're not expecting to see empty but still need to put it in
to defensively avoid a std::terminate.

And it's bizarre to have empty have super-throw behaviour if the method
wants to treat it like an optional success value, as you've suggested is
occasionally useful.

Why not just have exception() return the empty-state exception that
value() would have thrown?

> Certainly when using AFIO v2, I find myself writing a lot of
> afio_function().value();. I really wish it were more permissible to
> throw from destructors, then if the return were errored and you don't
> deal with it, it throws, no .value() needed.

It's legal; you just need to explicitly declare it as noexcept(false)
and only throw the exception if (!std::uncaught_exception()). Though
people will probably still yell at you about it.

That sort of policy can sometimes bite you with copyable types, though.
Sure, you could mark the source of a copy as "handled", but you don't
really know which one is going to be kept.

Boost list run by bdawes at, gregod at, cpdaniel at, john at