digitalmars.D.learn - How to fix opAssign signature
- Dan (25/25) Nov 02 2012 The following works, but I want to make opAssign in D take const
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/40) Nov 02 2012 Try the copy-then-swap idiom, which is both exception-safe and efficient...
- Dan (31/44) Nov 07 2012 Neat trick. But how do you deal with this?
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
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
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]AliNeat 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