C++ Logo

std-proposals

Advanced search

Re: [std-proposals] DR - std::visit non-intuitive behavior + new semantic for C-style variadic functions + pattern matching but better

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Tue, 6 Jun 2023 13:25:27 -0400
On Tue, Jun 6, 2023 at 1:02 PM Nikl Kelbon via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> really no one want describe why visit([](...) {}, value) just compiles into undefined behavior? We want to not change THIS behavior in standard?

... did you read what he said? He's saying that there are a lot of
possible complications from doing what you're doing, and that you need
to figure out what most of those are before any such change can be
seriously considered. It's not a defense of the status quo; it's a
statement that your suggestion is undercooked.

Your response isn't actually responding to the point being made.

In any case, I'm not sure I understand your point. The circumstance
you're talking about lies at an intersection between a primarily C
feature and a C++ construct. Those intersections tend to be where a
lot of UB lives.

Here's the thing: pretty much nobody uses C-style variadics with
variant visitation *on purpose*. If it happens, it happens purely by
accident. The user probably meant to do `auto&&...` but made a
mistake.

But this mistake is actually pretty rare. Why? Because in most cases,
users want to actually *do something* in that function with the
value(s) it is given. So most of them will catch it themselves when
they try to fill in `{}` with actual code, since they have no variable
name to look at (remember: they did not mean to use C-style
variadics).

So the only reason this might survive to an actual usage scenario is
if this is intended to be a default case. This would commonly be used
in something like "overload", a type that is built from a bunch of
lambdas to do overload resolution between their `operator()`
overloads. Basically, the code would look like this:

```
visit(
  overload{
  [](int i) {/*do stuff with i*/},
  [](std::string const& s) {/*do stuff with s*/},
  [](...) {/*default case. Needs no variable*/}
  }
  , value)
```
Since it doesn't need a variable name, it's easy to accidentally use
`...` instead of `auto&&...`.

But this is still *wrong*. We don't want people to use C-style
variadics. And the person who wrote this *also* didn't want to use
C-style variadics. We don't *want* C++ objects to be slipped into
C-style variadics.

So the only good solution here is to provoke a compile error on such calls.

Received on 2023-06-06 17:25:38