Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 25, 2013 D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Hi, In D, the : in a template parameter list only binds to 1 parameter. There is no way to specialize upon the entire template parameter list. Therefore you can't do much with the pattern matching and it's not powerful. Not a reasonable situation for a language aiming to be only the best. What is needed is the ability to bind to the whole template parameter list: template <class> struct get_class; template <class R, class C, class... A> struct get_class<R (C::*)(A...)> { typedef C type; }; Let's shorten the terms: <R, C, A...> @ <R (C::*)(A...)> And here's how this kind of specialization would work in D: template A[B] { struct C {} } template Foo[alias X, Y, Z @ X[Y].Z] { alias Z Foo; } void main() { alias Foo[A[bool].C] xxx; } You need a separate delimiter besides : which does not bind to individual parameters, but which binds to the set of parameters. I propose @ as the character which shall be the delimiter for the arguments to the pattern match, and the pattern match. On an unrelated note, I don't like the ! thing so I use []. Sorry for the confusion there. z |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl | By extension, template Foo[X, Y, Z @ X[Y], Y[Z]] { alias Y Foo; } |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl | Is this what you're looking for? struct Foo(T) { static void bar() { writeln("general"); } } struct Foo(T : A[B], A, B) { static void bar() { writeln("special"); } } void main() { Foo!(int).bar(); // general Foo!(int[int]).bar(); // special } |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | No, struct Foo(T) { static void f() { writeln("general"); } } struct Foo(T : A(B).alias C, A, B, C) { static void f() { writeln("special"); } } struct Bar(T) { struct Baz {} } struct Baz(T : A(B), A, B) { } void main() { Foo!(Bar!(int).Baz); Baz!(Bar!(int)); } |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl | Uneditable newsgroups. Simplest case. struct Bar(T) {} struct Foo(T : A(B), A, B) { static void f() {} } void main() { Foo!(Bar!(int)).f(); } |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl | On Saturday, 25 May 2013 at 12:13:42 UTC, Ahuzhgairl wrote:
> Uneditable newsgroups. Simplest case.
>
> struct Bar(T) {}
>
> struct Foo(T : A(B), A, B) {
> static void f() {}
> }
>
> void main() {
> Foo!(Bar!(int)).f();
> }
Two problems with that:
1. A(B) should be A!(B)
2. A won't bind to Bar because Bar is not a type, it is a template. A should be an alias.
This works:
struct Bar(T) {}
struct Foo(T : A!(B), alias A, B) {
static void f() {}
}
void main() {
Foo!(Bar!(int)).f();
}
|
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl Attachments:
| 2013/5/25 Ahuzhgairl <bulletproofchest@gmail.com>
> Uneditable newsgroups. Simplest case.
>
> struct Bar(T) {}
>
> struct Foo(T : A(B), A, B) {
> static void f() {}
> }
>
> void main() {
> Foo!(Bar!(int)).f();
> }
>
It would work.
struct Bar(T) {}
struct Foo(T : A!(B), alias A, B) { // 1, 2
static void f() {}
}
void main() {
Foo!(Bar!(int)).f();
}
1. should use A!(B), instead of A(B)
2. A would match to template, so should receive by TemplateAliasParameter.
Kenji Hara
|
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl | C++ example, works: template <class> struct A; template <template <class> class X, class Y> struct A<X<Y>> {}; template <class> struct B; int main() { A<B<int>> a; } But the following does not work: struct Foo {}; template <class> struct B { Foo x; } template <nontype P> struct A; template <auto M, auto C, nontype P> struct A<M C::*P> {} int main() { A<&B<int>::x> a; } D should be able to do both. |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl | On Saturday, 25 May 2013 at 12:43:42 UTC, Ahuzhgairl wrote: > C++ example, works: > > template <class> struct A; > template <template <class> class X, class Y> struct A<X<Y>> {}; > > template <class> struct B; > > int main() { > A<B<int>> a; > } As we've shown, you can do this in D. Instead of template templates, you use alias. > But the following does not work: > > struct Foo {}; > template <class> struct B { Foo x; } > > template <nontype P> struct A; > template <auto M, auto C, nontype P> struct A<M C::*P> {} > > int main() { > A<&B<int>::x> a; > } It's getting very hard to see what you're trying to do. I think it would help if you used real C++ and D syntax instead of inventing new syntax because I can't tell what you're trying to achieve and what semantics you expect of it. Please post a small example of real, working, compilable C++ that shows what you want to do, and we'll show you how to do it in D (assuming it is possible). |
May 25, 2013 Re: D's limited template specialization abilities compared to C++ | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahuzhgairl Attachments:
| 2013/5/25 Ahuzhgairl <bulletproofchest@gmail.com> > No, > > struct Foo(T) { > static void f() { writeln("general"); } > } > > struct Foo(T : A(B).alias C, A, B, C) { > static void f() { writeln("special"); } > } > > struct Bar(T) { > struct Baz {} > } > > struct Baz(T : A(B), A, B) { > } > > void main() { > Foo!(Bar!(int).Baz); > Baz!(Bar!(int)); > } > As I already shown, Baz!(Bar!(int)); could work in D. But, currently Foo!(Bar!(int).Baz); is not yet supported. I'm opening a compiler enhancement for related case, http://d.puremagic.com/issues/show_bug.cgi?id=9022 and right now I updated compiler patch to allow parameterize enclosed type by name/type/alias. https://github.com/D-Programming-Language/dmd/pull/1296 https://github.com/9rnsr/dmd/commit/b29726d30b0094b9e7c2e15f5802501cb686ee68 After it is merged, you can write it as follows. import std.stdio; struct Foo(T) { static void f() { writeln("general"); } } struct Foo(T : A!(B).C, alias A, B, alias C) { static void f() { writeln("special"); } } struct Bar(T) { struct Baz {} } void main() { Foo!(Bar!(int).Baz) x; x.f(); // prints "special" } Kenji Hara |
Copyright © 1999-2021 by the D Language Foundation