On 07/31/2017 12:14 PM, ag0aep6g wrote:
>
> You'd have to instantiate the inner template, too. Something like
> `&c.baz!"a".baz!()`, but that doesn't work. I don't know how you could
> make it work.
>
I tried this as well, and couldn't make it work either. Do you know if
it's supposed to work? I mean, do the spec mention this?
The funny part is that id does work with nested, non-eponymous templates:
```
class A {
template foo(string S) {
void bar()() {
import std.stdio;
writeln ("I'm bar");
}
void baz(this T)() {
import std.stdio;
writeln ("I'm baz at class ", typeid(T));
}
}
}
class B : A {
}
void main() {
A a = new A();
B b = new B();
void delegate() aBar = &a.foo!("a").bar!(); aBar();
void delegate() aBaz = &a.foo!("a").baz!(typeof (a)); aBaz();
void delegate() bBaz = &b.foo!("a").baz!(typeof (b)); bBaz();
}
```
OK, not directly with the "this" parameter... those you have to include
explicitly. However, this seems to be an unrelated problem: the "this T"
parameter seems to be only automatically deducted during function calls.
Even this doesn't work:
```
class A {
template foo(this T) {
void bar() {
import std.stdio;
writeln(typeid(T));
}
}
}
void main() {
A a = new A();
a.foo.bar();
}
```
But I think that's a completely separate issue (would that be a bug,
btw?) It's of course a trivial issue here, but it's just an example.
What use is it to allow "this T" parameters in raw template declarations
if they are not going to be automatically filled?
>
> (Assuming the inner baz is supposed to be `void baz(this T)() {}`.)
>
Sure :-)
> You'd still have to instantiate the inner baz in order to get a delegate
> of it. But even if we figured out how to do that, my guess is you don't
> want to specify `this T` explicitly.
>
> So how about a function literal:
>
> void delegate() aBaz = () => c.baz!(int, float)();
>
Yeah, that's the solution I was thinking about, but I don't know how
much of a performance hit the extra function call would be... would the
function literal extra indirection layer be eventually optimised out?
> That's right if you want to pass `args` explicitly, but `this`
> implicitly. If specifying `args` via IFTI is an option, then this works,
> too:
>
> ----
> class C {
> void baz(this T, args...)(args) {}
> }
>
> void main() {
> C c = new C();
> void delegate() aBaz = () => c.baz(1, 2.3, "four");
> }
> ----
>
> A function literal again, because you have to call baz in order to
> instantiate it (or you have specify `this T` and `args` explicitly). But
> you can't get a delegate from a call.
This wouldn't work in my case because the arguments ("args") are string
themselves, so the function call needs to look like:
c.baz!("one","two");
and not:
c.baz("one","two");
The reasons for that are a bit more complex, but let's say that in this
case I need the strings to be in the template parameters, I use those
strings to create an AliasSeq of values of different types that is then
sent to a "proper" variadic templated function.
Off topic, if anyone knows how to create a va_list dynamically, that
would save me a lot of problems!!