Thread overview | |||||
---|---|---|---|---|---|
|
November 02, 2012 How to fix opAssign signature | ||||
---|---|---|---|---|
| ||||
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; } |
November 02, 2012 Re: How to fix opAssign signature | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dan | 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 |
November 07, 2012 Re: How to fix opAssign signature | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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. :) > [snip] > 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 |
Copyright © 1999-2021 by the D Language Foundation