Have a template function register(T)() instantiated and executed at startup for all sub classes of a specific base class?

Arafel er.krali at gmail.com
Sun Sep 21 10:15:54 UTC 2025


That's something I've willing to do for a really long time too [1]. I 
would like to have a custom root object that automagically offers 
runtime introspection (given the current poor state of D in that area).

A template-this constructor will only work with one level of 
inheritance, as you have already discovered, and this is well known [2,3].

In my view the clean and cool solution would be to extend template this 
to static functions, including static constructors.

I don't think there is much opposition to that in principle, only nobody 
has implemented it yet (and unfortunately I don't know much about 
compilers, or I would have had a go at it myself).

So if you manage to make it work, please share your experience!

I think the closest I have been to this involves a mixin, and a module 
shared static this.

It's not perfect, but not too bad either. I'd still very much prefer to 
make it just as easy as inheriting from a base class.

A.

[1]: https://forum.dlang.org/post/pf8q9b$2dtb$1@digitalmars.com
[2]: 
https://forum.dlang.org/thread/mailman.1403.1361371073.22503.digitalmars-d@puremagic.com
[3]: https://forum.dlang.org/thread/hrxmezmyhdmkhqwbvcvi@forum.dlang.org

On 21/9/25 10:52, TwoOfCups wrote:
> This is a pretty open ended question here, there very well may not be 
> any way to do what I am trying to do with the constraints I have. I am 
> curious if anyone can think of something clever here.
> 
> So pretty much my goal here is some kind of automatic type registry for 
> a specific set of classes. It's something like an entity component 
> system. I need it to be a template function to do compile time 
> reflection on the classes for serialization and things like that.
> 
> The ideal end result would be that I could simply do:
> 
> ```
> class Sub : Base {}
> ```
> 
> And Sub would be registered automatically. Primarily it is this that I 
> am curious if there is **ANY** way to make happen. If I have to start 
> inserting mixins and stuff then I can imagine all sorts of ways to make 
> it work, but if I want the end result to be **as** clean as possible I 
> can't think of a way to make it work.
> 
> Something that is **so so so freakin** close to working is the following:
> 
> ```
> class regTclass(T){
>      pragma(crt_constructor)
>      extern(C)
>      static void reg(){
>          writeln("Registering type ", T.stringof);
>      }
> }
> 
> class Base {
>      this(this T)(){
>          pragma(msg, "Base: Subclass is ", T.stringof);
>          alias r = regTclass!(T);
>      }
> }
> 
> class Sub : Base {}
> ```
> 
> The above will work for one level of inheritance. An instance of 
> regTclass!Sub will be created and the reg call will be called at start 
> up auto magically. The flaw is it only works for one level, a class 
> SubSub : Sub {} will not get registered.
> 
> Is there any way to resolve this flaw? Is there some other route I could 
> take that doesn't require a mixin?
> 
> I know I can just insert a mixin and do it that way but I want things to 
> look as clean as possible. Even that tiny amount of boiler plate bothers 
> me a lot and this is a foundational system so that boiler plate will be 
> multiplied hundreds of times I am expecting. Probably in the end I will 
> just have to get over my aesthetic hang ups but I figured a forum post 
> was worth a shot.
> 
> 
> 



More information about the Digitalmars-d mailing list