On Wednesday, 7 November 2012 at 06:13:25 UTC, Rob T wrote:
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.

Duplicating the function, yes, but not duplicating the rvalue since it is moved in D. Isn't this analog to the C++ solution?

C++:
void f(T& a) { // for lvalues
    this->resource = a.resource;
    a.resetResource();
}
void f(T&& a) { // for rvalues (moved)
    this->resource = a.resource;
    a.resetResource();
}

D:
void f(ref T a) { // for lvalues
    this.resource = a.resource;
    a.resetResource();
}
void f(T a) { // rvalue argument is not copied, but moved
    this.resource = a.resource;
    a.resetResource();
}

T g() {
    T temp;
    temp.createResource();
    return temp; // D already moves temp!
                 // 'Named Return Value Optimization'
}

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.

You could implement a copy constructor 'this(this)' in your struct T and see when it is invoked to check when an instance is actually copied. I'd expect that invoking 'f(g());' with above implementation doesn't copy anything.

Reply via email to