The following code example is taken from the book
C++23 - The Complete Guide
by Nicolai M. Josuttis,
Leanpub, 2026
The code is licensed under a
Creative Commons Attribution 4.0 International License.
// raw code
#include <iostream>
#include <print>
#include <string>
#include <expected>
template<typename ValT, typename ErrT>
void print(const std::expected<ValT,ErrT>& exp)
{
if (exp) std::println("[value: {}]", *exp);
else std::println("[error: {}]", exp.error());
}
// convert string to int (might not be a valid int):
std::expected<int, std::string> asExpInt(const std::string& s)
{
// is the string a valid int (at the beginning)?
char first = s[0];
if (first == '-') first = s[1];
if (!std::isdigit(first)) {
return std::unexpected("\"" + s + "\" is no valid int");
}
return std::stoi(s);
}
int main()
{
auto square = [] (auto val) { return val * val; }; // unsafe: might overflow
using ExpString = std::expected<std::string, std::string>;
for (auto myExp : {ExpString{"42"}, ExpString{"data"}, ExpString{std::unexpected{"nodata"}}}) {
print(myExp);
auto exp = myExp.or_else([] (const auto& err) {
std::println("ERROR: {}", err);
return std::expected<std::string, std::string>{"fallback data"};
})
.and_then(asExpInt)
.or_else([] (const auto& err) {
std::println("ERROR: {}", err);
return std::expected<int, std::string>{42};
});
std::cout << " => ";
print(exp);
}
}