Boost logo

Boost :

Subject: Re: [boost] [outcome] Possible extensions/changes to std::experimental::expected
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-05-26 01:00:00


On 25/05/2017 19:44, Vicente J. Botet Escriba wrote:
> 3. uninitialized default constructed expected<T,E>

I've already stated my opinion on this elsewhere.

> Outcome doesn't implement comparisons between Outcomes. He pretend that
> we don't need them. In addition the mix of comparisons and implicit
> conversion give us some surprising cases as described in Andrzej blog.

I agree with Niall -- putting one directly in an ordered collection is
bizarre and if someone really wants to do that then it should be left up
to them to define what ordering makes sense to them. operator< should
absolutely not be implemented and I would hesitate before providing any
free standard ordering methods.

> The implicit conversion from T to expected<T,E> is a consequence of
> wanting that expected<T,E> should behave like a T. But this is not
> right. A expected<T,E> is not a T.

Implicit construction does not imply is-a, it implies is-superset-of.
Which is true, expected<T,E> is a superset of T. As the intent is to
naturally convey T as a wrapped return value of a method, the implicit
construction allows "return some_t_value;" as a simplified syntax and
the most natural one. Forcing users to use "return
make_expected(some_t_value);" instead would be a disservice and
discouragement, I think.

(In order to imply is-a then there must be a reverse conversion operator
from expected<T,E> to T, and that definitely should not exist, not even
as explicit.)

The caveat (and the reason make_unexpected is required) is where T and E
are compatible, eg. expected<int, int> or expected<double, int> etc. In
this case there is a possibility that someone intending to return an
error value might forget to use make_unexpected and end up with code
that compiles but is not correct. Requiring explicit make_expected does
mitigate this case but I'm not sure it's worth the hassle.

Outcome uses a different mitigation by restricting the possible types of
E, rendering the above case very unlikely (although not impossible,
since outcome<error_code> is legal).

> My question is why don't throw directly E?
>
> Some are requesting a way to get a specific exception from E, but either
> there is one exception that works for all and we can set it using some
> kind of trait or we need to add a trait parameter to expected to the the
> mapping :(
>
> Do we really want this to be configurable?

At least where E happens to be std::error_code it would be nice if it
threw std::system_error, since that is the exception designed for such
things. Otherwise I have no opinion.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk