Get class type parameters at compile time

js.mdnq js_adddot+mdng at gmail.com
Sun Dec 16 16:44:40 PST 2012


On Saturday, 15 December 2012 at 21:49:51 UTC, Philippe Sigaud 
wrote:
>>
>> Oops ;/ How do I get the number of type arguments if I don't 
>> know them
>> yet? I know this sort of seems wrong but somehow, to know how 
>> to alias the
>> class I need to know it's number of arguments. (I don't think 
>> it makes too
>> much sense with the type system but not sure how to solve the 
>> following
>> problem without it:
>>
>> http://forum.dlang.org/thread/**wacupbnlqgrfhaebdssd@forum.**
>> dlang.org#post-**yhhtuojlsgiykyrfhngl:40forum.**dlang.org<http://forum.dlang.org/thread/wacupbnlqgrfhaebdssd@forum.dlang.org#post-yhhtuojlsgiykyrfhngl:40forum.dlang.org>
>> )
>>
>
> I saw your other post. I'll try to understand what you're 
> trying to do in
> the dpaste you posted.
>
> I'm not sure I get your question, though. If a type is not 
> known in the
> current scope, you cannot determine its number of arguments, 
> because, well,
> it's not known.


I would like to be able to get the template args of a class 
inside the class:

class A(T1, T2)
{
    this() { pragma(msg, TemplateArgs!(typeof(this)).stringof); }
}

should print (T1, T2) or something similar.

When I run your code I get

tuple(true).

I'd also sort of like to setup an alias outside the class to 
refer to the class from inside without knowing the arguments 
explicitly

e.g.,


class A(T1, T2)
{
    this() { outer alias ... AB; } // ... is something like A!(T1, 
int) where T1 is inferred from being inside the class and int is 
explicit.
}

would be equivalent to something like

template A(T1,T2) { alias .A!(T1, int) A(T1); }

(this isn't suppose to be valid D code but pseudo-D code)

The idea is simply to reduce what the user outside the class has 
to know and type. If I were to parameterize a class:

class A(uT1, uT2, a,b,c,d,e,f,g,q,x,z,y) { }

and only uT1, uT2 were meant for the user and the rest were all 
statically known then I wouldn't want the user to have to type 
that stuff in... which is were aliases come in. Aliases don't 
seem to let you specify only a partial template list though, 
which, I think, is why you use templates?

But if I can create all the code inside the class that does this 
grunt work it would make it easier on the user and make it as 
transparent as possible. The goal is to make it feel like they 
are just using class A(uT1, uT2) rather than the other one. Since 
they are actually creating the class, the technique I use must 
work with any number of "user" template arguments.

In any case, being able to get the string name of a class, 
including the template arguments, would be very helpful in this.

Alternatively, having the ability to combine classes, even with 
different template arguments, would be useful(ah'la the other 
thread):

class Master(a,b,c,d,e,f,g,q,x,z,y) { xxx }
class User(uT1, uT2) { yyy }

Master(a,b,c,d,e,f,g,q,x,z,y) + User(uT1,uT2)
= struct MasterpUser(uT1,uT2,a,b,c,d,e,f,g,q,x,z,y) { xxx yyy }

which, if all of the master template arguments have default 
arguments then it should be easy to treat MasterpUser as if it 
were a User class and the user would not really know the 
difference between the two. (since MasterpUser contains all the 
functionality of User and the user does not know about the 
master's template args)

I, of course, provide the Master class, and the user(the 
programmer wanting the additional functionality, creates the User 
class.

It is very similar to inheritance except sort of static(no 
virtual functions, etc...). User, can, of course, also access 
data in Master(yyy could access Master's data) since they are 
actually the same class when combined.

It would be better to have a compile time inheritance construct 
as that is essentially what I'm trying to do:

class Master(a = 1,b = 2,c = 3,d = 4) { xxx }
class User(uT1, uT2) + Master!() { yyy [xxx is implicit] }

note that a class like

class User2(uT1, uT2) + Master!() { yyy [xxx is implicit] }

has no relationship to User(uT1, uT2) + Master!(). (well, it does 
but it at run time there is no common parent Master because there 
is no vtable. One could subtract the two classes to recover 
Master!() which would be non-empty and hence have overlap. This 
could only be carried out at compile time unless the 
functionality was added to the dynamic type system)

Anyways, I'm not sure if any of this is making sense but 
ultimately I'm trying to achieve something sort of like the above 
since I think D does not support such constructs. To do that, I 
need to be able to get the class name with it's type argument 
list without actually knowing them. typeof(this).stringof gets 
only the name... I need the other part.

I have seen someone mention a codeof trait, which is something I 
was also hoping for. This would make it easier to get what I want 
and also even implement an static algebra of classes and structs.












More information about the Digitalmars-d-learn mailing list