Allow struct constructors with all parameters optional

Quirin Schroll qs.il.paperinik at gmail.com
Thu Sep 5 18:08:46 UTC 2024


On Tuesday, 27 August 2024 at 08:48:19 UTC, Ogi wrote:
> ```D
> struct S {
>     this(int x = 0, int y = 0) {
>          writeln(i"S($(x), $(y))");
>     }
> }
> auto s1 = S(y: 42); // S(0, 42)
> auto s2 = S(); // default initialization
> ```

I don’t know if I like it or hate it. In contrast to the other 
ones, the nullary overload is visually present, whereas here, 
it’s not. Not being able to use the constructor with one or both 
arguments explicitly because you just aren’t allowed to define it 
is annoying, 100%. Working around that is possible, though:
```d
@safe:
import std.stdio;
struct S
{
     private enum Y { _ }
     this(int x, int y = 0) { writeln(i"S($(x), $(y))"); }
     this(Y = Y.init, int y) { this(0, y); }
}

void main()
{
     auto s = [ S(42), S(x: 42), S(y: 42), S(1, 2), S() ];
     // prints: S(42, 0), S(42, 0), S(0, 42), S(1, 2)
     // absent: S(0, 0)
}
```

The `Y = Y.init` makes the overload viable only through named 
arguments, so that `S(y: 42)` is possible.

I’d be definitely in favor of it if the proposal included 
defining and defaulting the nullary constructor, which would be 
required in this case. Something like that:
```d
struct S {
     default this(); // new
     this(int x = 0, int y = 0) {
          writeln(i"S($(x), $(y))");
     }
}
```

The nullary constructor can be `@disable`d, so making it also 
special in it being able to be `default`ed doesn’t really make 
difference.


More information about the dip.ideas mailing list