
On Sun, Jan 28, 2018 at 12:10 PM, VinÃcius dos Santos Oliveira via Boost < boost@lists.boost.org> wrote:
2018-01-28 12:12 GMT-03:00 degski via Boost
: 1. Use of outcome is more manual and cumbersome, i.e. more error-prone.
What is complex about the following?
outcome::result<int> convert(const std::string& str) noexcept { if (str.empty()) return ConversionErrc::EmptyString;
if (!std::all_of(str.begin(), str.end(), ::isdigit)) return ConversionErrc::IllegalChar;
if (str.length() > 9) return ConversionErrc::TooLong;
return atoi(str.c_str()); }
Or maybe about the following?
outcome::result<void> print_half(const std::string& text) { if (outcome::result<int> r = convert(text)) // #1 { std::cout << (r.value() / 2) << std::endl; // #2 } else { if (r.error() == ConversionErrc::TooLong) // #3 { OUTCOME_TRY (i, BigInt::fromString(text)); // #4 std::cout << i.half() << std::endl; } else { return r.as_failure(); // #5 } } return outcome::success(); // #6 }
Let's convert the first example to exceptions and see how much more readable your exceptions are:
int convert(const std::string& str) { if (str.empty()) throw ConversionErrc::EmptyString;
if (!std::all_of(str.begin(), str.end(), ::isdigit)) throw ConversionErrc::IllegalChar;
if (str.length() > 9) throw ConversionErrc::TooLong;
return atoi(str.c_str()); }
It looks the same to me. Let's try to convert the second example:
void print_half(const std::string& text) { try { int r = convert(text); std::cout << (r / 2) << std::endl; } catch (const ConversionErrc &e) { if (e == ConversionErrc::TooLong) { BigInt i = BigInt::fromString(text); std::cout << i.half() << std::endl; } else { throw; } } }
Also looks the same. So... you give us an example where exceptions are specially less verbose
Exception-neutral contexts, that is, when you can't handle the error. Instead of: f1(); if( error ) return error; f2(); if( error ) return error; f3(); if( error ) return error; You can just say: f1(); f2(); f3(); With exceptions, the compiler writes the ifs for you. (and I'm not challenging that your case is uncommon
because it looks very common to me), but then you generalize stating that it'll be like this everywhere.
Yes, there are very few try...catch contexts in most programs. Note that this is not the case in garbage-collected languages. For example, in Java you have to use try...finally to close files, handles, free mutexes, etc but in C++ this stuff happens automatically. Emil