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