www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How are extra copy constructor parameters used?

reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
The second item in the documentation mentions "any number of default 
parameters" when describing copy constructor syntax:

   https://dlang.org/spec/struct.html#struct-copy-constructor

1) I can't figure out how to use those extra parameters. For example, I 
can't find a special function name to call explicitly:

   S.__cctor(a, 42);  // No go

2) Unlike the examples there, I think the parameter should most usefully 
be defined as 'const' unless there is a special reason:

struct S {

   // const(S) instead of S:
   this(ref const(S) that) {
   }
}

Do you agree?

Thank you,
Ali
Dec 29 2021
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 30 December 2021 at 01:04:10 UTC, Ali Çehreli wrote:
 2) Unlike the examples there, I think the parameter should most 
 usefully be defined as 'const' unless there is a special reason:

 struct S {

   // const(S) instead of S:
   this(ref const(S) that) {
   }
 }

 Do you agree?
When the compiler generates a copy constructor for you, it always qualifies both the source and destination objects with `inout`: https://dlang.org/spec/struct.html#implicit-copy-constructors Therefore, when you write your own copy constructors, you should always use `inout` if possible, so that compiler-generated copy constructors will be able to copy instances of your struct that appear as members of other structs.
Dec 29 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/29/21 5:14 PM, Paul Backus wrote:

 Therefore, when you write your own copy constructors, you should always 
 use `inout` if possible, so that compiler-generated copy constructors 
 will be able to copy instances of your struct that appear as members of 
 other structs.
Excellent point. I noticed a typo in the documentation: struct A { this(ref return scope inout A rhs) immutable {} } That 'immutable' should be 'inout', right? Ali
Dec 29 2021
parent Paul Backus <snarwin gmail.com> writes:
On Thursday, 30 December 2021 at 02:04:30 UTC, Ali Çehreli wrote:
 On 12/29/21 5:14 PM, Paul Backus wrote:

 Therefore, when you write your own copy constructors, you 
 should always use `inout` if possible, so that 
 compiler-generated copy constructors will be able to copy 
 instances of your struct that appear as members of other 
 structs.
Excellent point. I noticed a typo in the documentation: struct A { this(ref return scope inout A rhs) immutable {} } That 'immutable' should be 'inout', right?
I think 'immutable' is correct here, since the usage examples look like this: A r1; const(A) r2; immutable(A) r3; // All call the same copy constructor because `inout` acts like a wildcard immutable(A) a = r1; immutable(A) b = r2; immutable(A) c = r3;
Dec 29 2021
prev sibling parent reply Tejas <notrealemail gmail.com> writes:
On Thursday, 30 December 2021 at 01:04:10 UTC, Ali Çehreli wrote:
 The second item in the documentation mentions "any number of 
 default parameters" when describing copy constructor syntax:

   https://dlang.org/spec/struct.html#struct-copy-constructor

 1) I can't figure out how to use those extra parameters. For 
 example, I can't find a special function name to call 
 explicitly:

   S.__cctor(a, 42);  // No go
Behold the pathetic hack! ```d import std.stdio:writeln; struct A { this(ref return scope A rhs) inout {} // copy constructor this(ref A rhs, int b = 7) inout { // copy constructor with default parameter if (b != 7) { rhs.b = b;//yes, modify the parameter, not the this object :( rhs.a = rhs.a; } else foreach (i, ref field; rhs.tupleof) field = this.tupleof[i] ; } this(this) disable; int a=4; int b=3; } void main() { A a = A(); A b = void; a.__ctor(b, 9); // because writing A b = A(a, 9); like a sane human is giving errors D: writeln(b.b); } ``` Replacing `a.__ctor(b, 9);` with `A b = A(a, 9);` is yielding: ```d onlineapp.d(26): Error: cannot implicitly convert expression `a` of type `A` to `int` ```
Dec 29 2021
parent Tejas <notrealemail gmail.com> writes:
On Thursday, 30 December 2021 at 04:42:06 UTC, Tejas wrote:
 On Thursday, 30 December 2021 at 01:04:10 UTC, Ali Çehreli 
 wrote:
 The second item in the documentation mentions "any number of 
 default parameters" when describing copy constructor syntax:

   https://dlang.org/spec/struct.html#struct-copy-constructor

 1) I can't figure out how to use those extra parameters. For 
 example, I can't find a special function name to call 
 explicitly:

   S.__cctor(a, 42);  // No go
Behold the pathetic hack! ```d import std.stdio:writeln; struct A { this(ref return scope A rhs) inout {} // copy constructor this(ref A rhs, int b = 7) inout { // copy constructor with default parameter if (b != 7) { rhs.b = b;//yes, modify the parameter, not the this object :( rhs.a = rhs.a; } else foreach (i, ref field; rhs.tupleof) field = this.tupleof[i] ; } this(this) disable; int a=4; int b=3; } void main() { A a = A(); A b = void; a.__ctor(b, 9); // because writing A b = A(a, 9); like a sane human is giving errors D: writeln(b.b); } ``` Replacing `a.__ctor(b, 9);` with `A b = A(a, 9);` is yielding: ```d onlineapp.d(26): Error: cannot implicitly convert expression `a` of type `A` to `int` ```
Ehh no need to get overly dramatic, I could've done `b.__ctor(a,9)` in order to prevent mutation via the parameter ```d import std.stdio:writeln; struct A { this(ref return scope A rhs) inout {} // copy constructor this(ref return scope const A rhs, int b = 7) inout { // copy constructor with default parameter if (b != 7) { this.b = b; this.a = rhs.a; } else foreach (i, ref inout field; rhs.tupleof) this.tupleof[i] = field; } this(this) disable; int a=4; int b=3; } void main() { A a = A(); A b = void; b.__ctor(a, 9); //b = A(a,9); //this still doesn't work :( writeln(b.b); writeln(b); } ```
Dec 29 2021