Const ref and rvalues again...

Rob T rob at ucora.com
Tue Nov 6 22:13:24 PST 2012


On Wednesday, 7 November 2012 at 02:34:25 UTC, martin wrote:
> On Wednesday, 7 November 2012 at 02:06:09 UTC, Rob T wrote:
>> What about the case where we want to pass a source argument 
>> either by reference or as a copy depending on the l/r value 
>> situation?
>>
>> eg
>> void f( ref a );
>> void f( a );
>>
>> --rt
>
> I don't get what you mean - that's why the 2 overloads are for 
> (you forgot the const/in keyword - beware! :))
>
> void f( in ref T a );
> void f( in T a );
>
> rvalue binds to the latter overload (argument not copied, but 
> moved directly).
> lvalue binds to the first overload (reference).
> Works with v2.060.

Sorry, my explanation was very poor. I'll try again.

I'm trying to describe the case where you want to modify the ref 
argument so that the source is also changed. For example, let's 
say you want to move a resource instead of coping it. Moving 
means the resource is transfered from one object to another, and 
the original is reset without destoying the resource. That way 
only one object can have the same resource. So for moving a 
resource, you cannot use "in ref" or "const ref", you need to 
just use "ref".

void f( ref T a ){
   // take resource away from a
   this.resource = a.resource;
   a.resetResource();
   // this now owns the resource
}

ref T works fine, but if you wish to use f( ref T a ) on a temp 
value returned from another function call, you'll need to 
overload f() to pass by value, which means creating a duplicate.

void f( ref T a ){
   // take resource away from a
   this.resource = a.resource;
   a.resetResource();
   // this now owns the resource
}

Example:

T g(){
    T temp;
    // create resource which is stored inside T
    temp.createResource();
    // move temp contents to return value
    return move(temp);
}

f( g() ); // won't compile with ref

It's annoying to have to create overloaded duplicates for a 
situation like moving, esp if the duplicate is a lot of code. In 
C++ the move problem was solved using && move semantics, and this 
is what I'm trying to emulate in D but I feel like I'm fighting 
with the language.

It is possible that D has a specific way of solving this problem 
that I'm not aware of yet, so correct me if I'm asking for 
something that is simply not needed.

I tried f( move(g()) ) but that fails to work. My best guess is 
that D does a hidden move of the temp instead of a copy to value. 
I can't say for sure because the documentation is not clear and 
is missing important details like this. I also cannot rely on 
clever compiler optimizations that may or may not be implemented 
as a guarantee.

--rt



More information about the Digitalmars-d mailing list