C++ Logo

std-proposals

Advanced search

Re: Operator for reference casting

From: Jean-Baptiste Vallon Hoarau <jeanbaptiste.vallon_at_[hidden]>
Date: Sun, 17 Jan 2021 21:45:12 +0100
>
> > I suppose you propose to automatically forward the variable at the last
> use and not before?
> No, it would always forward. Remember: forwarding doesn't do anything
> in and of itself. What does something is how the recipient of the
> forwarding process uses it.


But forwarding moves from your variable in half the cases, so that's not
quite correct?

But the meaning of a piece of syntax
> should not change based on where it is in a function or what follows
> it.
>

Why not, if this does what you want in most cases? At least correct
behavior is guaranteed, and it's an easy to understand, observable
mechanism.
Signature of functions can be hard to track down, if my rvalue-ref is moved
automatically on the first rvalue/forwarding-ref signature it means that we
now have to lvalue-ref-cast every use before the last or else an
unfortunate overload can silently break the code. A special operation on
last use is actually a more observable process.

This is also why we shouldn't allow implicit moves on the last use of
> a local variable in a function, even if a move operation was available
> to that usage. `return name` is OK to move from because that statement
> will *always* be the last thing executed in the function no matter
> where it appears relative to other code. But moving code around
> shouldn't affect the behavior in terms of overload resolution and the
> like.
>

The bigger problem with implicit moves is that it effectively changes your
program in ways that are hard to predict. If your object destructor has
side-effects and your code depends on it being called at the end of X
function scope, that's a bug (still going to be called, but with another
state).
This kind of type is fairly rare though and i would be ok with opt-in
implicit moves. "Pass the data in the most efficient way for the last use
if an overload is found" is a simple enough rule - and i think code that
performs semantically differently depending on reference qualifiers isn't
the kind of code to base language design decisions on. Furthermore you
still could get manual control by performing decay-copy etc, but that would
be "typing more to do the special case" instead of "typing more to do the
obvious thing".


Le dim. 17 janv. 2021 à 18:31, Drew Gross via Std-Proposals <
std-proposals_at_[hidden]> a écrit :

> The logger implementation we have is "deferred". When you call LogValue,
> it saves data to an in-memory data structure, and that data structure saves
> to disk later on. It means the expensive part is deferred until after all
> the important work is done, and can be optimized via batching some
> operations. It also means that the LogValue function can itself be
> optimized by moving from it's argument into the in-memory data structure,
> instead of copying, when provided with an rvalue.
>
> On Sun, Jan 17, 2021 at 9:21 AM Jason McKesson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> On Sun, Jan 17, 2021 at 4:27 AM Drew Gross via Std-Proposals
>> <std-proposals_at_[hidden]> wrote:
>> >
>> > 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) {
>> > LogValue(v);
>> > return f(v); // Oops, v was moved from! (Maybe, depending on
>> signature of LogValue)
>> > }
>> > ```
>>
>> Why would a logging function move from its parameter? It should take
>> it as a `const&`.
>>
>> > 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;
>> > }
>> > ```
>>
>> Again, why would `size` move from its parameter?
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2021-01-17 14:45:27