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

Rubn where at is.this
Fri Mar 30 02:47:49 UTC 2018


On Thursday, 29 March 2018 at 20:22:47 UTC, Dgame wrote:
> On Thursday, 29 March 2018 at 20:05:48 UTC, Rubn wrote:
>> On Thursday, 29 March 2018 at 19:11:30 UTC, Dgame wrote:
>>> Just to be sure it does not got los: You know that you can 
>>> avoid the temp/copy if you add one method to your struct, yes?
>>>
>>> ----
>>> import std.stdio;
>>>
>>> struct Big {
>>>     string name;
>>>     float[1000] values;
>>>
>>>     this(string name) {
>>>         this.name = name;
>>>     }
>>>
>>>     @disable
>>>     this(this);
>>>
>>>     ref auto byRef() inout {
>>>         return this;
>>>     }
>>> }
>>>
>>> void foo(ref const Big b) {
>>>     writeln(b.name);
>>> }
>>>
>>> void main() {
>>>     Big b = Big("#1");
>>>     foo(b);
>>>     foo(Big("#2").byRef);
>>> }
>>> ----
>>>
>>> That works like a charm and avoids any need for rvalue 
>>> references. Just add it as mixin template in Phobos or 
>>> something like that.
>>
>> Doesn't work with built-in types like float.
>
> Why would you want to use a float as a rvalue reference?

In templates to avoid template bloat with auto ref.

>> Just adds bloat for operators like opBinary if you want that 
>> to be ref.
>>
>> foo((a.byRef + b.byRef * c.byRef).byRef)
>>
>> // vs
>>
>> foo(a + b * c);
>>
>> It's kind of funny all this talk about allowing temporaries to 
>> bind to refs being messy, yet you can already bind a temporary 
>> to a ref in a messy way using that.
>
> Yeah, it is a bit messy. It is not perfect, but is does avoid 
> any temp var!
> Let's look at a Vector2f example with the following opBinary:
>
> ----
> auto opBinary(string op)(ref const Vector2f v) {
>     return Vector2f(mixin("this.x" ~ op ~ "v.x"), 
> mixin("this.y" ~ op ~ "v.y"));
> }
>
> void foo(ref const Vector2f v) {
>     writeln(v.x, ':', v.y);
> }
>
> foo((Vector2f(2, 4).byRef + Vector2f(4, 6).byRef).byRef);
> ----
>
> Since opBinary needs to be a template, you can combine my 
> solution with auto ref:
>
> ----
> auto opBinary(string op)(auto ref const Vector2f v) {
>     return Vector2f(mixin("this.x" ~ op ~ "v.x"), 
> mixin("this.y" ~ op ~ "v.y"));
> }
>
> void foo(ref const Vector2f v) {
>     writeln(v.x, ':', v.y);
> }
>
> foo((Vector2f(2, 4) + Vector2f(4, 6)).byRef);
> ----
>
> That is cleaner. :)

Just adding more template bloat and it is still messy, it's not 
like we are trying to find a work around to a problem. A solution 
already exists, the cleaner syntax you'd get with rvalue 
references (along with better compatibility with C++ and other 
benefits) can't be beat.



More information about the Digitalmars-d mailing list