Dynamic templated virtuals - I still often want them

Timon Gehr timon.gehr at gmx.ch
Sat Mar 12 13:00:24 UTC 2022


On 3/12/22 06:10, surlymoor wrote:
> On Thursday, 23 July 2020 at 02:38:27 UTC, Adam D. Ruppe wrote:
>> You might know about D's template this parameters, which adapt to the 
>> static type of a `this` reference on a call, or with the curiously 
>> recurring template pattern, which passes a derived class to the base 
>> class so the base class can inspect the derived class.
>>
>> Both of these are useful at times, but neither quite do what I have in 
>> mind here.
>>
>> Imagine this:
>>
>> ---
>> class Base {
>>      virtual string serialize(this This)() {
>>            return This.stringof; // just for example
>>      }
>> }
>>
>> class Derived : Base {
>>
>> }
>>
>> void main() {
>>     Base b = new Derived();
>>     assert(b.serialize() == "Derived");
>> }
>> ---
>>
>> That does NOT work today. For one, of course, D has no `virtual` 
>> keyword, but if you left that out, it would compile, but fail the 
>> assert because the static type of `b` passed to the template This is 
>> actually still `Base`.
>>
>> But imagine if `serialize` actually got a virtual table entry, just 
>> like if it wasn't a template at all, but each child class 
>> automatically got an instance of it made for itself.
>>
>> So it would be as if I wrote
>>
>> class Base {
>>      string serialize() {
>>            return Base.stringof;
>>      }
>> }
>>
>> class Derived : Base {
>>      override string serialize() {
>>            return Derived.stringof;
>>      }
>> }
>>
>> by hand. Of course, it is possible to do this kind of thing with mixin 
>> templates or the CRTP, but in both cases, the Derived class must 
>> actually write it in the child class, and if you don't there's no way 
>> to really tell; it will still compile and just use the base class 
>> implementation. Which might be OK but it isn't perfect.
>>
>> It would just be cool if the base class template was automatically 
>> instantiated again for the child class, while still working like a 
>> normal virtual call.
> 
> Man, I'd really kill for this right about now. I was designing something 
> that depended on the proposed behavior existing. My ignorance is my own 
> fault, of course, but still this would be a very cool feature for D.

The way I work around this is by putting template mixins into all 
subclasses, using `typeof(this)`. (It's a bit finicky though, template 
mixins are notorious for exposing forward reference compiler bugs.)


More information about the Digitalmars-d mailing list