C++ Logo


Advanced search

Subject: [std-proposals] Operator for reference casting
From: Bengt Gustafsson (bengt.gustafsson_at_[hidden])
Date: 2021-01-16 15:34:21

>> 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 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"?

Regardless, I'm not taking a stand here, I just wanted to investigate
what the possibilities are. Maybe having a forwarding operator that
works exacly as the current forward is better, but as I noted, with a
language feature we have more options than with a library function.
Before standardizing an operator we should look beyond just mimicking
what we have with forward and move, to see if there are definitions that
make more sense. This includes how many operators there should be, what
they should be valid for, what they should mean and how they should be

>> prefix => is a move operator which can only be applied to by value
>> variables and rvalue references (excluding universal references!).
> So if a function returns an lvalue reference, you can't move from it?
Exactly. Usually the party that returned the value to you don't expect
you to move it out, although strictly moving out is just a form of
modification. If you really wanbt to move something out that was not
returned to you by value or rvalue reference you can still use
std::move, which would signal that you have really thought this through
and is sure that move is the right thing to do.
>> In line with what I wrote before this means that the two operators would
>> have disjunct areas of applicability (you never have a choice as to
>> which one to apply, in each instance one or the other will be a
>> compilation error). So do we add or reduce confusion by having two
>> distinct spellings? I don't know, what do you think?
>> There is a possible tactical advantage with this definition in that it
>> is not possible to implement it in the library. The motivation for
>> introducing it as a language feature could thus be higher. This relies
>> on an urge to reduce the risks with the status quo, which if you as me
>> is not really the problem we're actually trying to solve; it is the
>> verbosity of std::forward.
> My understanding is that one of the problems of `std::forward` is that
> heavy usage of it actually impacts compile times, to the point where
> some libraries just do the whole `static_cast` bit directly. So it's
> not *just* a matter of verbosity.

Yes, this issue was floated earllier in this thread, and would also
probably be an advantage, my guess is that compiling -> would be
slightly faster than compiling a static cast but both would be
significantly faster than compiling forward, which involves a template
instantiation, and more complicated optimizations to get rid of the
unnecessary function call. However, I have noticed that forward and move
are among a few functions that get optimized away by MSVC even in debug
builds, so obviously it is possible to catch forward and move early in
the compilation process and avoiding the standard template instantiation
process. I haven't checked how other compilers codegen forward/move in
debug mode. If they shortcut it the win may not be as great as expected.
Someone mentioned a 15% speedup so apparently all compilers don't do it
(and I have no evidence that MSVC actually doesn't create the internal
AST data structures, just that the function call is absent from the
generated code).

> ------------------------------
> Subject: Digest Footer
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> ------------------------------
> End of Std-Proposals Digest, Vol 22, Issue 11
> *********************************************

STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups