Consider you have struct(T1, T2) Foo { } alias Foo!(int, float) X; You should be able to extract (int, float) from X. Often it is possible to get the parameters indirectly from members, but there doesn't seem to be a way to do this in the general case. I suggest: __traits(getTemplateParameters, X) which would yield a (int, float) tuple.
What would you use that for?
Trass3r: meta programming. It often happened to me that I wanted to get the template params. Sometimes I had to add alias declarations just to get access to them. I think this feature would make meta programming code simpler in some cases. PS: the example above should start with: struct Foo(T1, T2) { }
Well of course it's for metaprogramming. But I can't imagine a usecase at the moment so I asked for some examples ;)
As a partial workaround if you know the original template a type was instantiated with you can use: struct Foo(T1, T2) { } alias Foo!(int, float) X; template GetParams(R, alias X) { static if (is(R x == X!T, T...)) { alias T GetParams; } } void main() { pragma(msg, GetParams!(X, Foo)); } There's also an 'isTemplateInstance' now in std.traits.
I can have a pull ready soon for 2 traits: 1. Get the template out of the template instance (Foo!int => Foo) 2. Get the arguments used to instantiate the template (Foo!int => (int)) However I need some good names for these. I thought about using '__traits(getTemplateArgs, T)' and '__traits(getTemplateParent, T)', any better suggestions?
(In reply to comment #5) > I can have a pull ready soon for 2 traits: > > 1. Get the template out of the template instance (Foo!int => Foo) > 2. Get the arguments used to instantiate the template (Foo!int => (int)) > > However I need some good names for these. I thought about using > '__traits(getTemplateArgs, T)' and '__traits(getTemplateParent, T)', any better > suggestions? nazriel suggested: 'getTemplateName' 'getTemplateArgs' I think it's better because they line up nicely.
C++ lacks this particular ability and makes up for it by requiring templates to define internal aliases for type parameters. However, this is more tenuous for value parameters and simply impossible for template template parameters (in our case alias parameters). This has led to certain contortions and limitations; based on that experience I think we should add this ability.
(In reply to comment #5) > I can have a pull ready soon for 2 traits: I managed to lose the branch where I implemented this. I think I only did it partially though. @kenji: If you have this: template T(Args...) { } struct S(Args...) { } alias Tint = T!int; alias Sint = S!int; How do you get to the 'S' declaration from the instance? I want to implement these traits: static assert(is(__traits(getTemplateSymbol, SInt) == S)); static assert(is(__traits(getTemplateArgs, SInt) == int)); I've tried this in traits.c: Dsymbol *s = getDsymbol(o); TemplateInstace *ti = s->isTemplateInstance(); However that only works for Tint, and not for Sint. 's' is actually a StructDeclaration for Sint, not a TemplateInstance.
(In reply to comment #4) > As a partial workaround if you know the original template a type was > instantiated with you can use: > > struct Foo(T1, T2) > { > } > > alias Foo!(int, float) X; > > template GetParams(R, alias X) > { > static if (is(R x == X!T, T...)) > { > alias T GetParams; > } > } > > void main() > { > pragma(msg, GetParams!(X, Foo)); > } > > There's also an 'isTemplateInstance' now in std.traits. I don't see it ? But I added it in https://github.com/D-Programming-Language/phobos/pull/1367.
(In reply to comment #8) > (In reply to comment #5) > > I can have a pull ready soon for 2 traits: > > I managed to lose the branch where I implemented this. I think I only did it > partially though. > > @kenji: If you have this: > > template T(Args...) { } > struct S(Args...) { } > alias Tint = T!int; > alias Sint = S!int; > > How do you get to the 'S' declaration from the instance? I want to implement > these traits: > > static assert(is(__traits(getTemplateSymbol, SInt) == S)); > static assert(is(__traits(getTemplateArgs, SInt) == int)); > > I've tried this in traits.c: > > Dsymbol *s = getDsymbol(o); > TemplateInstace *ti = s->isTemplateInstance(); > > However that only works for Tint, and not for Sint. 's' is actually a > StructDeclaration for Sint, not a TemplateInstance. I made a pull request for this and other traits. It's in std.traits, which IMO is better than adding it to the compiler. https://github.com/D-Programming-Language/phobos/pull/1367
*** Issue 10890 has been marked as a duplicate of this issue. ***
There's now TemplateArgsOf and TemplateOf in std.traits: ----- import std.traits; struct Foo(T1, T2) { } alias Foo!(int, float) X; pragma(msg, TemplateArgsOf!X); // (int, float) -----