Skip to content

C++26 模式匹配 (Pattern Matching)

概述

模式匹配旨在为 C++ 提供类似 Rust match 的表达式化值匹配能力。

提案状态: P2688(inspect 表达式)处于活跃讨论阶段,尚未被 C++26 正式接受。

inspect 表达式

cpp
int classify(int x) {
    return inspect (x) {
        0            => 0;
        1 | 2 | 3   => 1;       // 多值匹配
        _            => -1;      // 通配符
    };
}

范围匹配

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

variant / optional / 结构体绑定

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);
    };
}

嵌套结构体和守卫子句:

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;
    };
}

与 visit + overloaded 对比

cpp
// C++20 — 需辅助模板
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 — 声明式
return inspect (v) {
    (int i)          => std::format("int: {}", i);
    (double d)       => std::format("double: {}", d);
};
维度visit + overloadedinspect
可读性需辅助模板声明式
嵌套匹配多层 visit原生支持
守卫条件if + throwif 子句
结构体解构不支持支持

穷尽性检查

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 => "→";
    };  // 无需 default
}

实现状态

编译器状态
GCC实验性分支
Clang / MSVC尚未实现

总结

inspect 为 C++ 带来结构化模式匹配,在可读性、嵌套匹配、穷尽性检查和结构体解构方面显著优于 visit + overloaded。虽尚未被 C++26 正式接受,但设计方向明确。

基于 MIT 许可发布