Jason : 

I suppose you propose to automatically forward the variable at the last use and not before? 

This is equivalent to the (pretty exciting) idea of Herb Sutter for new kind of functions parameters (in/out/inout/move/forward), see this talk

Le dim. 17 janv. 2021 à 10:27, Drew Gross via Std-Proposals <std-proposals@lists.isocpp.org> a écrit :
Some examples of when you don't want to forward a forwarding reference, might be easy to create bugs if it forwarded automatically:

1) A generic logging wrapper function
auto LoggedCall(auto >&& f, auto >&& v) {
    return f(v); // Oops, v was moved from! (Maybe, depending on signature of LogValue)
2) A generic concatenate function
auto Concatenate(auto >&& c1, auto >&& c2) {
    std::vector<decltype(c1)::value_type> result;
    using std::size;
    result.reserve(size(c1) + size(c2)); // Oops! c1 and c2 were moved from (OK only if size's signature is weird for c1/c2's type, but you get the point)
    // ... add c1 and c2 to result ...
    return result;

On Sat, Jan 16, 2021 at 9:14 PM Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sat, Jan 16, 2021 at 4:34 PM Bengt Gustafsson via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
> >> Given that a language feature has more wiggle room we could define two
> >> different operators with limitations in applicability that can't be
> >> enforced for a library feature such as std::forward / std::move.
> >>
> >> prefix -> is a forwarding operator which can only be applied to
> >> universal references, i.e. parameters declared with deduced template
> >> type and a && modifier.
> > And what of `auto &&t = expr;`? In terms of the rules for how `t` gets
> > deduced, it is just as much a forwarding reference as a parameter. And
> > it's just as reasonable to want to forward `t` as you would for any
> > parameter. And yet, the standard's definition of "is a forwarding
> > reference" would not include `t`.
> Practially you would want it to be possible to forward t here, and
> auto&& is a shortcut for the full template syntax. So yes, it should be
> included, in contrast with MyType&& x where you would use move (as you
> know it is a movable variable).

I've been thinking about this for the last few hours, and something
occurred to me:

We're kinda doing this backwards.

We're looking at `std::forward` as being this large, difficult-to-type
and not very easy to use wart in our code. And we want to make a
shorter version of it. But maybe the problem is not at the point of

Maybe the problem is that a "forwarding reference" is not a special
construct when it *should be*. After all, if a forwarding reference is
a special construct, then anytime you use it, we could say that the
compiler will *automatically* forward from it. And so we no longer
need to apply *any* syntax at the point of use.

So how do we do that? A forwarding reference parameter only gains
special forwarding reference status if it's declared like this:

template<typename T>
void func(T &&t);

But we now have a shorthand for that:

void func(auto &&t);

So what if we create a syntax specifically for forwarding references?
Just as a strawman syntax, we'll use this:

void func(auto >&&t);

There would be no long-form version of this with a template header; to
create an auto-forwarding-reference, you *must* use `auto`. And you
can't slip a cv-qualifier in there either.

In terms of the function declaration, it's the same as the above.
However, every use of `t` within the function should *automatically*
do the forwarding gymnastics. No syntax is needed at the point of use
to forward the expression's value category.

I feel like this is important because I'm really unsure of when I
*wouldn't* want to forward a usage of a forwarding parameter. And if
there's a time for that, we can always have a `std::lvalue` function
or something for it (if you want an rvalue, you'd use `std::move`).

This would work with any usage of `auto` (except maybe in template
parameters, but probably there too?):

auto >&&varname = expr;
auto >&&[x, y] = expr;

`varname` is an automatic forwarding reference, so all uses of
`varname` will forward it properly. Uses of `x` and `y` will properly
forward from the hidden variable. If the hidden variable is a struct
or array, `x` and `y` will carry the value category of the referenced
expression as appropriate. Otherwise, it'll return what `get` says to
return for the value category of the expression.

This cleans up a bunch of code at the point of use of forwarding
references, thus making them that much easier to use.

> >
> > I don't think it's reasonable to have language be functional or
> > non-functional based on nebulous properties like "is a forwarding
> > reference".
> I don't understand this, do you mean functional as in "working" or
> functional as in "pure functional programming"?

I meant "working".
Std-Proposals mailing list
Std-Proposals mailing list