On Fri, Sep 11, 2026 at 11:43 PM Jefferson Carpenter <jeffersoncarpenter2@gmail.com> wrote:
Forwarded to list, corrected

On Fri, Sep 11, 2026 at 4:47 PM Michael Park <mcypark@gmail.com> 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?

In this example we happen to only have a set of declarations, but patterns are richer in general.

Here's an example where it's not... obvious at all how overload resolution would work over the cases:

#include <string>
#include <variant>

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

void f(std::pair<int, Value> input) {
match (input) {
case [0, { int n }] => ;
case [0, { std::string s }] => ;
case [int tag, { int n }] => ;
case [int tag, { std::string s }] => ;
}
}

We have a pair of int and std::variant<int, std::string> being matched.
The pattern [0, { int n }] for example matches if .first == 0 and variant has an int.
The rest of the patterns should be fairly intuitive I think.

There's not really much of an overload to be formed across those cases.

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

Ah, I only showed the match statement because you had mentioned wanting a switch.
You can also use match as an expression. For example:

#include <variant>

struct MyClass { int num; };

int f(std::variant<MyClass, int> x) {
return match (x) {
case { MyClass myclass } => myclass.num;
case { int n } => n;
};
}

>
> 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}: ...;}"

The problem with switch is that the syntax for switch is not structured at all.
The syntax for switch is essentially:

switch (value) statement

The statement there makes it such that any arbitrary sequence of statements can
be written with cases written somewhere sometimes.

It also has too much baggage around fall-through and requiring break, etc.

The committee has been pretty firm on "leave switch alone".

On Fri, Sep 11, 2026 at 4:47 PM Michael Park <mcypark@gmail.com> 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@lists.isocpp.org> 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@gmail.com> 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@gmail.com> wrote:
>> > >
>> > > That looks good.
>> > >
>> > > On Thu, Sep 10, 2026 at 3:58 PM Jens Maurer <jens.maurer@gmx.net> 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@lists.isocpp.org
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion