Why Traditional Error Codes Fall Short

Most of us have lived through the era of returning int error codes or using output parameters like bool parse(Config&, std::string& err). The problem isn’t that they don’t work — they do — it’s that they force the caller to remember a convention, and the compiler can’t help you when you forget to check the result. I’ve seen production bugs caused by a missed if (!rc) because the function looked like it returned a value.

Modern C++ gives us types that make the contract explicit in the signature, so the compiler becomes your first line of defense.

Enter std::optional

std::optional (C++17) models a value that may be absent. It’s perfect for functions that either produce a result or have nothing meaningful to return — think lookup tables, cache reads, or parsing a single integer.

// Returns the parsed port if the string is a valid number in range.
std::optional<uint16_t> parse_port(const std::string& s) {
    if (s.empty()) return std::nullopt;
    try {
        long v = std::stol(s);
        if (v < 0 || v > 65535) return std::nullopt;
        return static_cast<uint16_t>(v);
    } catch (...) {
        return std::nullopt;
    }
}

The caller writes:

if (auto port = parse_port(cfg["port\