C++ - expected and Result Patterns (C++23)

Overview

Estimated time: 45–60 minutes

Model operations that can fail without exceptions using std::expected (C++23) or similar result types. Improve clarity and testability for predictable errors.

Learning Objectives

  • Use std::expected to return values or errors.
  • Design error enums/structs and propagate errors ergonomically.

Prerequisites

Basic usage

#include 
#include 
#include 
#include 

std::expected to_int(std::string_view s){
  int out{};
  auto first = s.data();
  auto last  = s.data() + s.size();
  auto res = std::from_chars(first, last, out);
  if (res.ec == std::errc{}) return out;
  return std::unexpected(res.ec);
}

Consuming results

#include 
#include 

void print_result(const std::expected& r){
  if (r) std::cout << *r << "\n";
  else   std::cout << std::make_error_code(r.error()).message() << "\n";
}

Common Pitfalls

  • Overusing exceptions and expected together—pick a dominant strategy for layers.
  • Ignoring unexpected construction for errors; be explicit about error type.

Checks for Understanding

  1. When is expected preferable to exceptions?
  2. How do you access the error?
Show answers
  1. For predictable, frequent errors and when you want value-like return handling without stack unwinding.
  2. Use .error() or pattern-match equivalent helpers.

Exercises

  1. Write expected parse_double that returns a message on failure.
  2. Chain two expected-returning functions and propagate errors early.