Overloading based on named arguments is possible, here’s how
Quirin Schroll
qs.il.paperinik at gmail.com
Tue May 7 11:58:59 UTC 2024
What one might want to do:
```d
struct X
{
this(int x) { … } // 1
this(int y) { … } // 2
}
void main()
{
X(x: 1); // call 1
X(y: 2); // call 2
}
```
Of course, that doesn’t work. Parameter names aren’t part of the
function signature and therefore, the two constructors clash.
It’s not an ambiguity error on the call-site, it’s just that the
two constructors have the same mangle.
However, I found a neat trick how it can be done. For each
problematic overload, add an enum type with one value:
```d
enum f_x_t { value }
enum f_y_t { value }
```
Then, change each overload so that it takes a value of the
respective enum type as their *first* parameter, defaulted to the
obvious value:
```d
struct X
{
this(f_x_t = f_x_t.value, int x) { … } // 1
this(f_y_t = f_y_t.value, int y) { … } // 2
}
```
Then, the two constructors have different mangles and can be
distinguished in the object file. In code, using named arguments,
one can re-order the parameters and because the enum parameters
are defaulted, they need no arguments.
```d
import std.stdio;
struct X
{
private enum f_x_t { value }
private enum f_y_t { value }
this(f_x_t = f_x_t.value, int x) { writeln("X(int x) called
with ", x); }
this(f_y_t = f_y_t.value, int y) { writeln("X(int y) called
with ", y); }
}
void main()
{
X(x: 1); // X(int x) called with 1
X(y: 2); // X(int y) called with 2
}
```
For ordinary functions, the following works as well:
```d
void f_x(int x) { writeln("f(int x) called with ", x); }
void f_y(int y) { writeln("f(int y) called with ", y); }
alias f = f_x;
alias f = f_y;
```
The only downside is that it does not work for constructors,
possibly among others.
More information about the Digitalmars-d
mailing list