I'm going by these two quotes:
> 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).
> I'd prefer the value in a new feature to "look" more like a lambda
body anyway, complete with a return statement (or instead of a full
lambda body, just a single expression that gives the value).
Consider this example that I gave:
struct MyClass { int num; };
int f(std::variant<MyClass, int> x) {
int result = match (x) {
case { MyClass myclass } => myclass.num;
case { int n } => n;
};
}
Breaking down the first quote:
> What I'd like to see is an expression-level construct
match is an expression-level construct here.
> for visiting variants.
This is visiting variants.
> It needs to let me bind at least a single variable (the value inside the variant)
{ MyClass myclass } and { int n } are each binding the value inside the variant.
> (possibly letting me destructure it)
Yep, you can even do that using structured bindings inside the braces.
> and run statements of code yielding a value.
In this case, the => myclass.num; and => n; are both yielding a value.
To run statements of code yielding a value, the existing solution is to use
an immediately-invoked-lambda. Ideally, we'll adopt do expressions for C++29.
> (These statements mainly introduce new variables, but may utilize all variables in scope).
Yep, either immediately-invoked-lambdas or do expressions would let you introduce new
variables, and the variables introduced in the patterns are usable in anything on the right
side of => .
Onto the second quote.
> I'd prefer the value in a new feature to "look" more like a lambda body anyway
I'm not quite sure what you mean by "the value in a new feature"... but if you mean
essentially the right side of =>, then you can literally have an immediately-invoked-lambda
there, or you can (hopefully) have a do expression which "looks" more like a lambda body.
> complete with a return statement
With immediately-invoked-lambdas, you literally get a return statement that yields the value
as the result of match. With do expressions, you get do_return to yield the value as
the result of match and return returns from the surrounding function which is a very useful
functionality.
> (or instead of a full lambda body, just a single expression that gives the value).
The example I gave is exactly this.
=> myclass.num; and
=> n; are just a single expression
that gives the value.
So yeah, to me, it seems to offer virtually everything you're describing. Perhaps you can
elaborate in more detail as to what you believe the gaps are.