www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to fix opAssign signature

reply "Dan" <dbdavidson yahoo.com> writes:
The following works, but I want to make opAssign in D take const 
ref D.
It needs to still print "(dup here)". How can this be done?

Thanks
Dan

----------------
import std.stdio;

struct A {
   char a[];
   this(this) { a = a.dup; writeln("(dup here)"); }
}
struct B { A a; }
struct C { B b; }
struct D {
   C c;
   // How can I make this take const ref D other
   ref D opAssign(ref D other) {
     c = other.c;
     return this;
   }
}

void main() {
   D d, d2;
   d2 = d;
}
Nov 02 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/02/2012 05:29 AM, Dan wrote:
 The following works, but I want to make opAssign in D take const ref D.
 It needs to still print "(dup here)". How can this be done?

 Thanks
 Dan

 ----------------
 import std.stdio;

 struct A {
 char a[];
 this(this) { a = a.dup; writeln("(dup here)"); }
 }
 struct B { A a; }
 struct C { B b; }
 struct D {
 C c;
 // How can I make this take const ref D other
 ref D opAssign(ref D other) {
 c = other.c;
 return this;
 }

Try the copy-then-swap idiom, which is both exception-safe and efficient: import std.algorithm; // ... ref D opAssign(D other) { swap(c, other.c); return this; } There may be corner cases where this is not efficient, but considering that assignment involves two sub-operations (make a copy of the new state and destroy the old state), the above is doing exactly that. (It is the same idiom for strongly exception-safe operator= in C++.) That has been the observation that led me to understand that by-value is the way to go with struct opAssign. Please let us know whether it has weaknesses. :)
 }

 void main() {
 D d, d2;
 d2 = d;
 }

Ali
Nov 02 2012
prev sibling parent "Dan" <dbdavidson yahoo.com> writes:
On Friday, 2 November 2012 at 15:56:47 UTC, Ali Çehreli wrote:
     ref D opAssign(D other) {
         swap(c, other.c);
         return this;
     }

 There may be corner cases where this is not efficient, but 
 considering that assignment involves two sub-operations (make a 
 copy of the new state and destroy the old state), the above is 
 doing exactly that. (It is the same idiom for strongly 
 exception-safe operator= in C++.)

 That has been the observation that led me to understand that 
 by-value is the way to go with struct opAssign. Please let us 
 know whether it has weaknesses. :)

 Ali

Neat trick. But how do you deal with this? D d1; const(D) d2; d1 = d2 As soon as I add an assoc array to A I need to implement an opAssign if I want to be able to assign a const(A) to an A. And I would want to be able to do that for this composition. Note the cast - is that safe? import std.stdio; struct B { private A _a; property auto a(const ref A other) { _a = other; } } struct A { int[1024] i; /// Very big making pass by value bad choice string[string] h; auto opAssign(const ref A other) { h = cast(typeof(h))other.h.dup; } } void main() { B b; A a = { [0], [ "foo" : "bar" ] }; b.a = a; } Thanks Dan
Nov 07 2012