Boost logo

Boost :

Subject: Re: [boost] [outcome] Possible extensions/changes to std::experimental::expected
From: Peter Dimov (lists_at_[hidden])
Date: 2017-05-25 21:57:11

Andrzej Krzemienski wrote:
> 2017-05-25 23:34 GMT+02:00 Peter Dimov via Boost <boost_at_[hidden]>:
> > Andrzej Krzemienski wrote:
> >
> >> Instead, rewrite observer functions like this:
> >>
> >> bool has_value() const
> >> {
> >> if (BOOST_UNLIKELY(_is_in_empty_state()))
> >> __builtin_unreachable();
> >>
> >
> > Please no. This is horrible. Actually it's doubly horrible; merely
> > horrible would be putting the above in value(). In an observer
> > function... it's just evil.
> Can you explain?

What is there to explain? This makes calling has_value undefined if empty
("narrow contract"), which makes the user responsible of checking empty()
before doing ANYTHING with a result/outcome object. This applies to each and
every result/outcome object you receive from somewhere.

    auto r = function();
    if( r.empty() { /* always have to do this*/ }
    else if( r.has_value() ) { /* otherwise UB here */ }

As I said, I don't like undefined behavior for its own sake, and I most
certainly don't like putting a "Requires: not empty" contract on every
function, including observers.

Putting a contract is not even a good fit for value(), because it already
checks and throws, to enable

    auto r = function().value();

where you go from noexcept land to exception land. If UB on empty, goodbye
one liner, you still need to save the outcome and check for empty first,
before retrieving value().

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