Boost logo

Boost :

Subject: Re: [boost] [err] RFC
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-11-17 17:54:29

Le 17/11/2015 01:45, Domagoj Saric a écrit :
> copy-paste:
> ---------------------------------------------
> err - yet another take on C++ error handling.
> We have throw and std::error_code, what more could one possibly want?
> ---------------------------------------------
> What, primarily, makes (Boost.)Err different from other proposals is
> the ability to (using latest C++ features) detect/distinguish between
> temporaries and 'saved' return values by using two different class
> templates (result wrappers), fallible_result (for rvalues) and
> result_or_error (for lvalues) and thus minimise or often completely
> eliminate any extra verbosity:
> If we had a function foo() that produces bar_t objects but can fail
> with an err_t, up till now we had two options:
> * bar_t foo() throw( err_t );
> * optional<bar_t> foo( err_t & );
> Err enables the library writer to write a single API and a single
> implementation:
> err::fallible_result<bar_t, err_t> foo();
> where fallible_result is the class template that wraps
> temporaries/rvalues returned from functions and its member functions
> are all declared with && (i.e. callable only on rvalues) so you get a
> compiler error if you save it to an auto value and try to do anything
> with it. The two exceptions are the implicit conversion operators to:
> - bar_t, which will either return bar_t or throw err_t and which is
> used for the 'EH code path'
> bar_t my_bar( foo() );
> - err::result_or_error<bar_t, err_t> which is used for the 'oldsk00l
> nothrow error code path'
> err::result_or_error<bar_t, err_t> maybe_bar( foo );
> if ( maybe_bar ) { print( *maybe_bar ); }
> else { log( maybe_bar.error() ); }
> Also, if the fallible_result rvalue is left uninspected and contains
> an error its destructor will throw (which AFAICT should be safe
> considering it is an rvalue and no other exception can possibly be
> active at the same time) - this makes code that uses Err enabled
> libraries/APIs but relies on EH almost indistinguishable from 'classic
> EH' APIs (almost because the one difference that remains is with the
> immediate use of the return value: because of the wrapper class one
> can no longer write foo().do_something() but has to implicitly use the
> -> operator and write foo()->do_something() where the -> operator will
> check-and-throw if foo() did not succeed).
> To wrap up, this approach gives the user the immediate and fine
> grained control over which error handling mechanism he/she wants to
> use while allowing the developer to write a single API and
> implementation - AFAICT it is a no brainer replacement for
> <system_error>, it is less verbose and much more efficient ;-)
> ps. the small library @ is by no means a
> finished product, it contains no tests or documentation but 'it works'
> (i.e. it is used in the, also upcoming,
>'m bringing it to public view for
> scrutiny, discussion and guidance lest I steer in the wrong direction ;)

I like the idea of having a movable only class that is used as the
result of a function and that ensure that the error is checked
(TBoost.Expected has an ensure_read error class that terminates if the
error is not read) and the conversion to a copyable that is used to pass
this result as parameter to a function.

However how do you prevent that the user forget to check for the error
in the converted err::result_or_error<void, err_t>?

Wondering if expected<T, ensure_read<R>> and expected<T, R> wouldn't be
equivalent if expected<T, R> is constructible from expected<T,


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