Templates for instantiating derived class

Adam Ruppe destructionator at gmail.com
Mon Sep 20 22:23:43 UTC 2021


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.


More information about the Digitalmars-d-learn mailing list