digitalmars.D - Overloading based on named arguments is possible,
- Quirin Schroll (63/63) May 07 What one might want to do:
- cc (13/17) May 07 Interesting! Looks like this can be done via template arguments
- Martin Tschierschke (3/6) May 08 Cool!
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.
May 07
On Tuesday, 7 May 2024 at 11:58:59 UTC, Quirin Schroll wrote: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.Interesting! Looks like this can be done via template arguments as well. ```d struct X { this(string f = "x")(int x) { writeln("X(int x) called with ", x); } this(string f = "y")(int y) { writeln("X(int y) called with ", y); } } X(x: 1); // X(int x) called with 1 X(y: 2); // X(int y) called with 2 ```
May 07
On Wednesday, 8 May 2024 at 04:46:26 UTC, cc wrote: [...]X(x: 1); // X(int x) called with 1 X(y: 2); // X(int y) called with 2 ```Cool!
May 08