C++ Logo

std-discussion

Advanced search

Re: Proposal for switch statement extension

From: Michael Park <mcypark_at_[hidden]>
Date: Fri, 11 Sep 2026 14:47:18 -0700
Hello, P1371R3 <http://wg21.link/p1371r3> was the previous iteration of
pattern matching. The most recent version
discussed in EWG was P2688R5 <https://wg21.link/p2688r5>, which did not
achieve consensus for C++26.

I'm currently working on R6 of P2688, which I will be submitting for the
upcoming Sept mailing.
I'm planning to present it in Buzios in November, and targeting C++29.

As a small preview, with R6 the code you wrote:

switch (x) { // Assume x is of type std::variant<MyClass, int>
case (MyClass myclass): { a(myclass); break; }
case (int n): { b(n); break; }
}

would be written like this (CE link: https://godbolt.org/z/fMW1xdjz6):

match (x) { // Assume x is of type std::variant<MyClass, int>
case { MyClass myclass } => a(myclass);
case { int n } => b(n);
}

The semantics are slightly different, as these do not form an overload set.
They are still matched
in order top-to-bottom, and require exact match. As such, for examples like
this, it works out to be
the same (you can reorder the handlers in the match example, it's the same).

The braces denote that we're matching the element inside the variant.
Without the braces,
it matches the whole variant rather than the stored element.

match (x) { // Assume x is of type std::variant<MyClass, int>
case { auto elem } => c(elem);
// vs
case auto whole => d(whole);
}

This distinction of payload vs whole extends to optional for example as
well:

match (opt) { // Assume opt is of type std::optional<int>
case {} => ; // nullopt
case { auto elem } => ; // elem is int
// vs
case auto whole => ; // whole is optional<int>
}

There's... A LOT more to share, but this is one of the important core ideas
of R6.

On Thu, Sep 10, 2026 at 3:49 PM Jefferson Carpenter via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Actually the two are more or less the same. I think it would be much
> more readable to allow a statement-seq ending with a retrun statement
> to provide the value like a lambda expression than to try to construct
> matchers and extractors for whatever intermediate values you need.
>
> On Thu, Sep 10, 2026 at 5:07 PM Jefferson Carpenter
> <jeffersoncarpenter2_at_[hidden]> wrote:
> >
> > I definitely agree that matchers and extractors should not be language
> > features. Implementing these is like trying to invert a function.
> >
> > If the inspect expression is non-void, can a statement-seq be used
> > with a return statement to implement the value?
> >
> > - Jefferson
> >
> > On Thu, Sep 10, 2026 at 4:30 PM Jefferson Carpenter
> > <jeffersoncarpenter2_at_[hidden]> wrote:
> > >
> > > That looks good.
> > >
> > > On Thu, Sep 10, 2026 at 3:58 PM Jens Maurer <jens.maurer_at_[hidden]>
> wrote:
> > > >
> > > >
> > > > Please read the pattern matching proposal:
> > > >
> > > > P1371 Pattern Matching
> > > > https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf
> > > >
> > > > Jens
> > > >
> > > >
> > > > On 9/10/26 21:05, Jefferson Carpenter via Std-Discussion wrote:
> > > > > Hi all,
> > > > >
> > > > > I'd like to propose some "syntactic sugar" that ties the switch
> > > > > statement language feature to the std::variant standard library
> type.
> > > > > The idea is to make the process of visiting a variant much cleaner
> and
> > > > > simpler.
> > > > >
> > > > > Basically it has to support the following code transformation:
> > > > >
> > > > > switch (x) { // Assume x is of type std::variant<MyClass, int>
> > > > > case (MyClass myclass): { a(myclass); break; }
> > > > > case (int n): { b(n); break; }
> > > > > }
> > > > >
> > > > > to the following:
> > > > >
> > > > > struct Unnamed {
> > > > > void operator()(MyClass const& myclass) { a(myclass); }
> > > > > void operator()(int const& n) { b(n); }
> > > > > };
> > > > > Unnamed{}(x);
> > > > >
> > > > > so that the code jumped to from each case is transformed into a
> > > > > function call operator overload. A braced-enclosed code block
> ending
> > > > > in a break statement may be required after each case "label" even
> when
> > > > > there are no variables declared in the body or if fallthrough were
> > > > > desired so that the code that must be moved is outlined and easy to
> > > > > move.
> > > > >
> > > > > This could potentially be extended to other non-std::variant types
> if
> > > > > there were a mechanism like std::get, but I haven't explored this
> at
> > > > > all.
> > > > >
> > > > >
> > > > > This would be very useful to me, as I've written a lot of
> > > > > programming-language-like programs and use std::variant
> extensively to
> > > > > represent expression trees.
> > > > >
> > > > > It would make C++ much more viable for programs like this to have
> the
> > > > > code for visitors easier to read and type than calls to std::visit.
> > > > >
> > > > >
> > > > > Warm Regards,
> > > > > Jefferson Carpenter
> > > >
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

Received on 2026-09-11 21:48:01