On Monday, 20 September 2021 at 22:16:47 UTC, rjkilpatrick wrote:
auto opBinary(string op)(int rhs) const if (op == "+") {
return new Super(_a + rhs); // Creates of type Super
even when called from derived class
}
Make this
auto opBinary(string op, this This)(int rhs) .............
return new This(_a + rhs);
}
The template this param is the static type it is called on.
https://dlang.org/spec/template.html#template_this_parameter
Note though that this is the static type. If you do
Super thing = new Derived();
thing + 5;
it will still return Super since that's the type it was called
through. If you want it to actually return derived, you'll have
to add a virtual factory function:
class Super {
protected Super factory() { return new Super(); }
}
class Derived : Super {
override Derived factory() { return new Derived(); }
}
Then you can call obj.factory to get the right dynamic type.
(forward args as needed etc.)
Some kind of `return new this(...)` would be good, but that's
not possible.
You can do `return new typeof(this)(...);` fyi but it is again
the static type of this, which will be whatever it is where it is
defined. This is a useful trick if you were to make that factory
function a mixin template or something though.