On 17/11/2015 13:45, Domagoj Saric wrote:
Err enables the library writer to write a single API and a single implementation: err::fallible_result
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 which is used for the 'oldsk00l nothrow error code path' err::result_or_error maybe_bar( foo ); if ( maybe_bar ) { print( *maybe_bar ); } else { log( maybe_bar.error() ); }
Nitpicking on this, now that we're in an auto world it seems like a step backwards to introduce an API that relies on the declared type of a variable to alter behaviour. There should be methods on fallible_result that return these values explicitly instead.
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)
Throwing from a destructor can cause abrupt termination (or undefined behaviour in some compilers); there are no conditions in which it should be considered "safe". Additionally I'm not convinced that no exception can be active at the same time. Consider function call parameters -- you could easily have one of these get constructed but not consumed yet, and then another parameter throws an exception, resulting in destruction of your object during the throw of an exception.