www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to convert member function to free function?

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
How can I rewrite foo() function as a free-function that won't 
cause struct copying? My simplified code is:
========
struct S
{
     ref S foo() return
     {
         return this;
     }
}

void main()
{
     S().foo().foo().foo();
}
========
If I write it like "auto foo(S s) { return s; }" then statement 
in main() will copy value of S three times and I want to avoid 
this.
Sep 18 2020
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Sep 18, 2020 at 06:20:41PM +0000, Andrey Zherikov via
Digitalmars-d-learn wrote:
 How can I rewrite foo() function as a free-function that won't cause
 struct copying? My simplified code is:
 ========
 struct S
 {
     ref S foo() return
     {
         return this;
     }
 }
 
 void main()
 {
     S().foo().foo().foo();
 }
 ========
 If I write it like "auto foo(S s) { return s; }" then statement in
 main() will copy value of S three times and I want to avoid this.
Why can't you return by ref, which would also avoid the copying? ref S foo(return ref S s) { return s; } T -- Let's not fight disease by killing the patient. -- Sean 'Shaleh' Perry
Sep 18 2020
parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Friday, 18 September 2020 at 18:43:38 UTC, H. S. Teoh wrote:
 Why can't you return by ref, which would also avoid the copying?

 	ref S foo(return ref S s) { return s; }
Compiler errors out: onlineapp.d(9): Error: function onlineapp.foo(return ref S s) is not callable using argument types (S) onlineapp.d(9): cannot pass rvalue argument S() of type S to parameter return ref S s
Sep 18 2020
prev sibling parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Friday, 18 September 2020 at 18:20:41 UTC, Andrey Zherikov 
wrote:
 How can I rewrite foo() function as a free-function that won't 
 cause struct copying?
I found solution: ======== struct S { int i = -1; this(int n) {i=n;writeln(&this," ",i," ",__PRETTY_FUNCTION__);} this(ref return scope inout S rhs) inout {i=rhs.i+1;writeln(&this," ",i," ",__PRETTY_FUNCTION__);} ~this() {writeln(&this," ",i," ",__PRETTY_FUNCTION__);} ref auto getRef() return { writeln(&this," ",i," ",__PRETTY_FUNCTION__); return this; } } ref auto foo(return ref S s) { writeln(&s," ",s.i," ",__PRETTY_FUNCTION__); return s; } void main() { S(5).getRef().foo().foo().foo(); } ======== Output confirms that there is no copying happens: ======== 7FFDE98BDDF0 5 S onlineapp.S.this(int n) ref 7FFDE98BDDF0 5 onlineapp.S.getRef() ref return 7FFDE98BDDF0 5 onlineapp.foo(return ref S s) ref system 7FFDE98BDDF0 5 onlineapp.foo(return ref S s) ref system 7FFDE98BDDF0 5 onlineapp.foo(return ref S s) ref system 7FFDE98BDDF0 5 void onlineapp.S.~this() ========
Sep 18 2020