bearophile Wrote: > Paul D. Anderson: > > My struct has a dynamic array as a member -- that seems to be the problem. > > This code doesn't compile: > > > > struct S { > > int x; > > int[] a; > > } > > > > S foo(const S b) { > > S other = b; > > return other; > > } > > void main() {} > > This compiles, oh joy: > > struct S { > int x; > int[] a; > } > S foo(const S b) { > S other; > other.x = b.x; > other.a = b.a.dup; // the dup is necessary here > return other; > } > void main() {} > > > The idea now is to find a way to encapsulate that manual copying & dupping > into some overloaded operator of S. But I have failed so far. Operator > overloading in D2 is not an easy thing, it needs training. (That's why I have > recently asked for the compiler to be strict to avoid wrong usages of the > operator overloading.) > > Bye, > bearophile
Yes, thanks to you and biozic for finding the root of the problem. Here's a piece of code that demonstrates the problem: //------------- struct S { int x; int[] a; // including this postblit causes an error because the default // constructor it applies to doesn't allow const argument. /+this(this) { a = a.dup; }+/ // adding a const to the argument of this constructor allows case 2. this(const S s) { x = s.x; a = s.a.dup; } // including or excluding this constructor doesn't change // the compilability. /+this( S s) { x = s.x; a = s.a.dup; }+/ // an opAssign with a const argument allows case 3. S opAssign(const S s) { this.x = s.x; this.a = s.a.dup; return this; } // including this doesn't make a difference. // I think this is the same as the default opAssign. /+S opAssign(S s) { this.x = s.x; this.a = s.a.dup; return this; }+/ } // case 1: no const. According to the spec this is // a copy constructor in action. S foo(S b) { S other = b; return other; } // case 2: const, but assignment requires the creation of a // non-const S from before assignment. S bar(const S b) { S other = S(b); return other; } // case 3: const, but creation and assignment are separate. // this is a default construction and opAssign(const). S foo(const S b) { S other; other = b; return other; } // case 4:const. According to the spec this is // a copy constructor in action, but it goes awry. // does not compile. S foo(const S b) { S other = b; return other; } void main() {} /---------------------- So I understand better now, thanks, what is wrong. I'm a little disappointed that there is apparently no way to implement case 4 for any struct with a reference. Paul p.s. Does it make any sense to send this over to the D forum to get more eyes on the problem?