Skip to content

std::expected (C++23)

In a Nutshell

Holds either the desired value T or an unexpected error E — a type-safe, zero-overhead error propagation mechanism that replaces exceptions and std::pair<T, Error> patterns.

#include <expected>

Core API Quick Reference

OperationSignatureDescription
Construct (success)expected(T value)Wrap a normal value
Construct (error)expected(unexpect_t, E err)Wrap an error (std::unexpected{err})
Check successbool has_value() const noexceptWhether it holds a normal value
Implicit boolexplicit operator bool() const noexceptSame as has_value
Get valueT& value()Get reference to value (throws on error)
Get errorconst E& error() constGet reference to error
DereferenceT& operator*()Get value (unchecked, UB if error)
Chain transformauto transform(F&& f)If value, apply f and wrap result
Chain and_thenauto and_then(F&& f)If value, call f and return its expected result
Error branchauto or_else(F&& f)If error, call f to handle it
Error transformauto transform_error(F&& f)If error, apply f to the error
Create successstd::expected<T, E>(value)Factory: construct success directly
Create errorstd::unexpected{err}Factory: construct unexpected for implicit conversion to expected

Minimal Example

cpp
// Standard: C++23
#include <expected>
#include <iostream>
#include <string>

std::expected<int, std::string> divide(int a, int b) {
    if (b == 0) return std::unexpected{"division by zero"};
    return a / b;
}

int main() {
    auto r1 = divide(10, 3);
    if (r1) std::cout << *r1 << "\n"; // 3

    auto r2 = divide(10, 0);
    if (!r2) std::cout << r2.error() << "\n"; // division by zero

    // Chained call
    auto r3 = divide(20, 4).transform([](int v) { return v * 2; });
    std::cout << *r3 << "\n"; // 10
}

Embedded Applicability: High

  • Zero-overhead abstraction: size equals sizeof(T) + sizeof(E) plus a discriminator flag, no heap allocation
  • Replaces exception handling, suitable for embedded environments with exceptions disabled (-fno-exceptions)
  • More type-safe than error code + output parameter patterns, forcing callers to handle errors
  • Chain operations (transform/and_then) compose complex workflows while keeping code linear and readable

Compiler Support

GCCClangMSVC
121619.36

See Also


Some content adapted from cppreference.com under CC-BY-SA 4.0 license

Built with VitePress