
On Wed, Jul 12, 2017 at 4:27 PM, Gavin Lambert via Boost < boost@lists.boost.org> wrote:
On 13/07/2017 05:11, Emil Dotchevski wrote:
Allow me to clarify. Suppose I have a function foo which returns FILE * on success, some EC1 on failure, and another function bar(), which calls foo and returns an int on success, some EC2 on failure. I believe in terms of Outcome this would be:
outcome::result
foo() noexcept; outcome::result
bar() noexcept { if( auto r=foo() ) { //no error, use r.value(), produce the int result or return EC2(x). } else { return ______; } } What do you recommend in place of _____?
FWIW, I believe the Outcome code would be:
outcome::result
bar() noexcept { auto r = foo(); if (r) { //no error, use r.value(), produce the int result or return EC2(x). } else { return make_ec2_from_ec1(r.error()); } }
This works great in the case of exception specifications too. Right? :) Essentially, the problem is that any framework that requires enumeration of the possible error types has the same problems as statically enforced exception specifications. Consider that if bar is generic, it has no idea what error types foo() may return.
The general recommendation (as Andrzej has already pointed out) is to use the same error code type so that you don't need to do conversions (which might be lossy), but if you insist on using alternate types
I don't insist on using different error types, the use case is when one _has_ a different error type, which in C++ is common.
then you have no choice but to do an error domain conversion.
In case of Outcome, yes. In case of Noexcept, no, it has been designed to be able to propagate the original error object.