C++ Logo

std-discussion

Advanced search

Re: Proposal for switch statement extension

From: Jefferson Carpenter <jeffersoncarpenter2_at_[hidden]>
Date: Sat, 12 Sep 2026 01:10:24 -0500
Forwarded to list, corrected

On Fri, Sep 11, 2026 at 4:47 PM Michael Park <mcypark_at_[hidden]> wrote:
>
> 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.

Why not? Do you have an example handy for why they shouldn't form an
overload set?

>
> 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.

Really a switch statement isn't the right thing to compare this with
because a switch statement doesn't normally bind new variables.

What I'd like to see is an expression-level construct for visiting
variants. It needs to let me bind at least a single variable (the
value inside the variant) (possibly letting me destructure it), and
run statements of code yielding a value. (These statements mainly
introduce new variables, but may utilize all variables in scope).

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

What I'm proposing should be a distinct language feature from one for
inspecting a
value like the Pattern Matching proposal introduces. Can you propose
an extension to
the switch statement instead? You could write "switch (opt) { case
{}: ...; case {let a}: ...;}"

On Fri, Sep 11, 2026 at 4:47 PM Michael Park <mcypark_at_[hidden]> wrote:
>
> Hello, P1371R3 was the previous iteration of pattern matching. The most recent version
> discussed in EWG was 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-12 06:43:26