Template this parameter in constructor

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Feb 21 13:48:21 PST 2016


On 2/21/16 11:48 AM, Vlad Leberstein wrote:
> Hi! I'm struggling to use "Template This Parameters" feature(as
> described in https://dlang.org/spec/template.html#TemplateThisParameter)
> in class constructor. But it's usage isn't documented very clearly and
> I'm not even sure if it's supposed to work this way. Consider the
> following example:
>
> class C1 {
>      this(this This)() {
>          pragma(msg, "C1 constructor: "~__traits(identifier, This));
>      }
> }
>
>
> class C2 : C1 {
>      this(this This)() {
>          pragma(msg, "C2 constructor: "~__traits(identifier, This));
>          super();
>      }
> }
>
>
> class C3 : C2 {
>      this(this This)() {
>          pragma(msg, "C3 constructor: "~__traits(identifier, This));
>          super();
>      }
>
> }
>
>
> int main(string[] args) {
>      auto test = new C3();
>
>      return 0;
> }
>
> The output is:
> C3 constructor: C3
> C2 constructor: C3
> C1 constructor: C2
>
> As you can see this works but doesn't produce the desired behavior - we
> can't get static type of the C3 class in C1 constructor. I suspect that
> it's somehow related to the fact that templated functions can't be virtual.
>
> And here comes the question: Is this a bug or the way things are
> supposed to work(and hence should be documented)?

This isn't a bug. Here is what happens.

1. template this is assigned the compile-time type of the object *when 
the function is called*.

2. A base class constructor is called from the next derived constructor. 
So C2's constructor is called from C3's, and C1's constructor is called 
from C2's.

So it follows that the template this type will be the next derived 
constructor (or the type itself if that is the most derived type), 
because that's the compile-time type the object's ctor is called with.

> It would be immensely helpful to have such kind of compile-time
> information(for usecases vastly similar to what's described in
> http://forum.dlang.org/thread/mailman.1403.1361371073.22503.digitalmars-d@puremagic.com)
> cause currently I'm using some kind of CRTP pattern with multilevel
> inheritance support instead and it feels very very very weird in D world.

I think you may be able to do something like this:

this(T = typeof(this))()
{
    super!T();
}

But I'm not sure if it works.

-Steve


More information about the Digitalmars-d-learn mailing list