When to use std::expected instead of exceptions

853 Views Asked by At

When should I use std::expected and when should I use exceptions? Take this function for example:

int parse_int(std::string_view str) {
    if (str.empty()) {
        throw std::invalid_argument("string must not be empty");
    }
    /* ... */
    if (/* result too large */) {
        throw std::out_of_range("value exceeds maximum for int");
    }
    return result;
}

I want to distinguish between different errors when using this function, so it's useful that I can throw different types of exceptions. However, I could also do that with std::expected:

enum class parse_error {
    empty_string,
    invalid_format,
    out_of_range
};

std::expected<int, parse_error> parse_int(std::string_view str) noexcept {
    if (str.empty()) {
        return std::unexpected(parse_error::empty_string);
    }
    /* ... */
    if (/* result too large */) {
        return std::unexpected(parse_error::out_of_range);
    }
    return result;
}

Are there any reasons to use std::expected over exceptions (performance, code size, compile speed, ABI), or is it just stylistic preference?

0

There are 0 best solutions below