C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Defect report for std::apply (or apply_perfectly)

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Mon, 11 Mar 2024 11:56:58 +0000
On Mon, 11 Mar 2024, 10:09 Frederick Virchanza Gotham via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> On Sun, Mar 10, 2024 at 2:07 PM Jonathan Wakely wrote:
> >
> > But this is exactly the same behaviour you get with
> > Func(std::get<0>(t), std::get<1>(t), std::get<2>(t)),
> > or equivalently with std::move(t) for each argument.
>
>
> But I wouldn't call a function like that. Nor do I think would anyone
> else. If I were calling a function called 'Func' with a list of
> arguments, I wouldn't pass the Rvalues as Lvalues. Therefore if I were
> to write out "std::get" by myself, I would use 'static_cast' or 'move'
> or 'forward' to pass the arguments properly. __Unless__ I didn't want
> perfect forwarding for some reason or other.
>
>
> > For the hundredth time, stop showing how to code something and
> demonstrate
> > why it's needed. Your motivation is "when I use tuple in a way that's
> not expected
> > to work, it doesn't work".
>
>
> The reason I coded it was to show that I thought the following made more
> sense:
>
> (1) Lvalue references get passed as Lvalue references
> (2) Rvalue references get passed as Rvalue references
> (3) Non-reference types get passed by reference (the same kind of
> reference as how the tuple was passed)
>
> Your suggestion to pass the tuple by Rvalue reference helps me to
> achieve (1) and (2), but not (3). When it comes to (3), your
> suggestion makes the non-reference types get passed by Rvalue
> reference -- but I don't want this.
>


So what you want is:

 std::apply(Func, tuple<T0&, T1&, T2&&>(t))

Don't change/replace std::apply, just use a helper function to do that. Now
it works with more than just std::apply.

Or don't create a strange tuple mixing values and references in the first
place, create the second string on the stack, then you can use:

std::apply(Func, std::forward_as_tuple(s2, s, std::move(s)));

We can't know how appropriate this is for your real case, because your
example passing both s and move(s) to the same function is clearly
unrealistic and ill-advised.

Received on 2024-03-11 11:58:19