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.