Skip to content

C++26 Pattern Matching

Overview

Pattern matching aims to provide C++ with Rust-like match expression-based value matching capabilities.

Proposal status: P2688 (inspect expression) is under active discussion and has not yet been officially accepted for C++26.

inspect Expression

cpp
int classify(int x) {
    return inspect (x) {
        0            => 0;
        1 | 2 | 3   => 1;       // Multi-value match
        _            => -1;      // Wildcard
    };
}

Range Matching

cpp
int classify_char(char c) {
    return inspect (c) {
        'a' .. 'z'  => 0;
        'A' .. 'Z'  => 1;
        '0' .. '9'  => 2;
        _            => 3;
    };
}

variant / optional / Structured Binding

cpp
#include <variant>
#include <optional>
#include <format>

using Value = std::variant<int, double, std::string>;

std::string format_value(Value const& v) {
    return inspect (v) {
        (int i)          => std::format("int: {}", i);
        (double d)       => std::format("double: {}", d);
        (std::string s)  => std::format("str: {}", s);
    };
}

std::string unwrap(std::optional<int> const& opt) {
    return inspect (opt) {
        (int value)     => std::format("got {}", value);
        (std::nullopt)  => "empty";
    };
}

struct Point { int x; int y; };
std::string classify_point(Point const& p) {
    return inspect (p) {
        (Point { .x = 0, .y = 0 })  => "origin";
        (Point { .x = x, .y = 0 })  => std::format("x-axis at {}", x);
        (Point { .x = 0, .y = y })  => std::format("y-axis at {}", y);
        (Point { .x = x, .y = y })  => std::format("({}, {})", x, y);
    };
}

Nested structs and guard clauses:

cpp
struct Line { Point start; Point end; };
bool is_horizontal(Line const& l) {
    return inspect (l) {
        (Line { .start = { .y = y1 }, .end = { .y = y2 } }) => y1 == y2;
    };
}

int categorize(int x) {
    return inspect (x) {
        0                      => 0;
        (n) if (n < 0)        => -1;
        (n) if (n % 2 == 0)   => 2;
        (n)                    => 3;
    };
}

Comparison with visit + overloaded

cpp
// C++20 — requires helper template
template <typename... Ts>
struct overloaded : Ts... { using Ts::operator()...; };
auto fmt = std::visit(overloaded{
    [](int i)          { return std::format("int: {}", i); },
    [](double d)       { return std::format("double: {}", d); },
}, v);

// C++26 — declarative
return inspect (v) {
    (int i)          => std::format("int: {}", i);
    (double d)       => std::format("double: {}", d);
};
Dimensionvisit + overloadedinspect
ReadabilityRequires helper templateDeclarative
Nested matchingMultiple levels of visitNatively supported
Guard conditionsif + throwif clause
Struct destructuringNot supportedSupported

Exhaustiveness Checking

cpp
enum class Direction { Up, Down, Left, Right };
std::string to_arrow(Direction d) {
    return inspect (d) {
        Direction::Up    => "↑";
        Direction::Down  => "↓";
        Direction::Left  => "←";
        Direction::Right => "→";
    };  // No default needed
}

Implementation Status

CompilerStatus
GCCExperimental branch
Clang / MSVCNot yet implemented

Summary

inspect brings structured pattern matching to C++, significantly outperforming visit + overloaded in readability, nested matching, exhaustiveness checking, and struct destructuring. Although not yet officially accepted for C++26, the design direction is clear.

Released under the MIT License