rvalues -> ref (yup... again!)

Rubn where at is.this
Tue Mar 27 00:30:24 UTC 2018


On Monday, 26 March 2018 at 14:40:03 UTC, Atila Neves wrote:
> C++ T&& (Rvalue reference) -> D T

Not really, in C++ it is an actual reference and you get to 
choose which function actually does the move. In D it just does 
the copy when passed to the function. So you can't do this in D.

void bar(T&& t)
{
     // actually move contents of T
}

void foo(T&& t)
{
     bar(std::forward<T>(t)); // Can't do this in D without making 
another actual copy cause it isn't a reference
}

> If replacing const T& with T chafes, I understand. I used to 
> feel that way too. It's _possible_ that would incur a penalty 
> in copying/moving, but IME the cost is either 0, negligible, or 
> negative (!).
>
> As mentioned above, if calling C++ code there's no choice about 
> using T instead of const T&, so for pragmatic reasons that 
> should be allowed. But only there, because...
>
>> Can you please explain these 'weirdities'?
>> What are said "major unintended consequences"?
>
> Rvalue references. They exist because of being able to bind 
> temporaries to const T& in C++, which means there's no way of 
> knowing if your const T& was originally a temporary or not. To 
> disambiguate C++11 introduced the type system horror that are 
> rvalue references (which also do double-duty in enabling 
> perfect forwarding!).

What's a concrete example that you would be required to know 
whether a const& is a temporary or not. I don't really see it 
otherwise. The solution everyone is saying to use as an 
alternative would be the literal case of how it would be 
implemented in the language.

> D doesn't have or need rvalue references _because_ of not 
> allowing temporaries to bind to ref const(T). You get move 
> semantics in D without the pain. That's a win in my book.
>
> Atila

I've come across a few pains of such. It make be easier to use 
but it comes at a performance hit. In part binaries become huge 
because of how "init" is implemented.

struct StaticArray(T, size_t capacity)
{
     size_t length;
     T[capacity] values;
}

Copying the above structure copies unnecessary data for any 
move/copy operation. Eg when length = 0, it'll still copy 
everything. This includes initialization.


More information about the Digitalmars-d mailing list