On Tuesday, 27 August 2024 at 08:48:19 UTC, Ogi wrote:
> 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:
@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:
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.