I do not understand copy constructors

Learner learner at gmail.com
Thu Aug 12 09:36:14 UTC 2021


On Thursday, 12 August 2021 at 09:14:02 UTC, Paul Backus wrote:
> On Thursday, 12 August 2021 at 08:42:27 UTC, Learner wrote:
>>     struct A {
>>         int[] data
>>         this(ref return scope A rhs) { data = ths.data.dup; }
>>     }
>>
>>     Generating an `inout` copy constructor for `struct B` 
>> failed, therefore instances of it are uncopyable
>>
>> What is an `inout` copy constructor? What should I change in A?
>
> When the compiler generates a copy constructor for a struct, it 
> generates it with the following signature:
>
> ```d
> this(ref return scope inout(typeof(this)) src) inout
> ```
>
> (Source: 
> https://dlang.org/spec/struct.html#implicit-copy-constructors)
>
> Notice that both the `src` object and the object being 
> constructed (`this`) are qualified with `inout`.
>
> `inout` is a special type qualifier that allows the same 
> function to be used for mutable, `const`, and `immutable` 
> arguments. To make this work, the compiler imposes heavy 
> restrictions on what you can do with an `inout`-qualified 
> object--only operations that are valid on mutable, `const`, 
> *and* `immutable` objects are allowed for `inout`.
>
> (Source: https://dlang.org/spec/function.html#inout-functions)
>
> `A`'s copy constructor does not have any type qualifiers on its 
> `rhs` argument or its `this` reference, so both default to 
> mutable. In other words: `A`'s copy constructor can only be 
> used to construct a mutable copy from a mutable original 
> object. It *cannot* be used to construct an `inout` copy from 
> an `inout` object.
>
> In order to make the generated copy constructor work, you need 
> to give `A` a copy constructor that can copy `inout` objects. 
> There are two possibilities here:
>
> 1. Make `A`'s copy constructor `inout`: `this(ref return scope 
> inout A rhs) inout`
> 2. Make `A`'s copy constructor `const`: `this(ref return scope 
> const A rhs) const`

While option 2. is not working:

     struct A {
         int[] data;
         this(ref return scope const A rhs) const {}
     }
     Error: Generating an `inout` copy constructor for `struct A` 
failed, therefore instances of it are uncopyable

Option .1 actually works, with an empty body, while it fails with 
the actual body:

     struct A {
         int[] data;
         this(ref return scope inout A rhs) inout { data = 
rhs.data.dup; }
     }
     Error: cannot implicitly convert expression 
`dup(cast(const(int)[])rhs.data)` of type `int[]` to 
`inout(int[])`

It seems that there is no easy way to transition from a postblit 
to a copy constructor, no?





More information about the Digitalmars-d-learn mailing list