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

Dgame r.schuett.1987 at gmail.com
Thu Mar 29 20:22:47 UTC 2018


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?

> 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. :)


More information about the Digitalmars-d mailing list