DIP 1018--The Copy Constructor--Community Review Round 1

RazvanN razvan.nitu1305 at gmail.com
Sat Jan 5 14:02:06 UTC 2019


On Saturday, 22 December 2018 at 23:26:47 UTC, Dru wrote:
> First I want to say that I hope it gets implemented
> Semantic consistency demands it:
>
> B b;
> A a = b; //calls this(B) or this(ref B)
> A a2 = a; //*should* call this(ref A)
>

That is indeed the case.

>
> I have a few points:
>
> 1) "ref" vs "ref const" dilemma
>
> The user can overload different kinds of copy ctors,
> but what is the *default* copy ctor ?
> I think the default copy ctor should be "ref const"
> - "ref const" is safer and fits most cases
> - "ref" has priority over "ref const" so the user can simply 
> overload
> and his "ref" ctor will be used instead of the default
>
There is no default copy constructor. You define the copy 
constructors you need.
There is a generated copy constructor which is defined if a 
struct does not have a copy constructor, but has fields that 
define one. Currently, the generation strategy is pretty dumb, 
but I plan on enhancing it with a later DIP, in which copy 
constructors are generated based on the qualifiers of the fields 
copy constructors:

struct A
{
     this(ref A rhs) immutable {}
     this(ref A rhs) {}
}

struct B
{
     this(ref B rhs) immutable {}
}

struct C
{
     A a;
     B b;
}

For C, one can simply generate the following copy constructors:

this(ref C rhs) immutable
{
     this.a = rhs.a;
     this.b = rhs.b;
}

this(ref C rhs)
{
     this.a = rhs.a;     // copy constructor call
     this.b = rhs.b;     // error, no copy ctor
}

The first one succeeds in type checking, while the second one 
does not. I think that this is a superior design to the one in 
the DIP, but Walter thinks that we should keep things simple in 
the first iteration and add enhancements later.
>
> 2) "Generating copy constructors"
>
> Should the user care when a constructor is "generated" if 
> semantics are consistent ?
> May just say there is *always* a default copy ctor that can be 
> overriden by the user.
> The implementation of default ctor can change and use memcpy as 
> needed.
>
The copy constructor is generated, only if there are copy 
constructors for some fields that need to be called. The idea is 
that if a struct defines a copy constructor, it cannot be blitted 
in any circumstances; the copy constructor should always be used.
>
> 3) Not very related but maybe also needs a fix:
> I noticed that init to rvalue of a different type is weird 
> right now
> A a1 = b; //calls this(ref B)
> A a2 = B(); //does not call this(ref B)

It cannot call it, because the constructor receives a reference 
and you are passing an rvalue. That is not even a copy 
constructor, but a regular constructor, so if you want the 
compiler to call it, simply delete the ref.


More information about the Digitalmars-d mailing list