I do not understand copy constructors

Paul Backus snarwin at gmail.com
Thu Aug 12 09:14:02 UTC 2021


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`


More information about the Digitalmars-d-learn mailing list