// note: C++23 - a newer compiler than the one this course is built
// against is needed (GCC 14, Clang 18, MSVC 19.40 or later, -std=c++23)
#include <expected>
#include <optional>
#include <print>
#include <string>
// *** before: ***
// std::optional said "there is no value" but never said why; the reason
// travelled in an out parameter, in an error code beside the result,
// or in an exception
std::optional<int> parseOld(const std::string& text) {
if (text.empty()) return std::nullopt; // empty? not a number? too big?
return std::stoi(text);
}
// *** in version C++23: ***
std::expected<int, std::string> parse(const std::string& text) {
if (text.empty())
return std::unexpected("the text is empty");
for (char c : text)
if (c < '0' || c > '9')
return std::unexpected("not a number: " + text);
return std::stoi(text); // the value itself, as usual
}
int main() {
if (auto good = parse("42"); good)
std::println("{}", *good);
auto bad = parse("4x2");
if (!bad)
std::println("error: {}", bad.error()); // the reason is carried along
std::println("{}", parse("").value_or(-1));
}