Taking the address of an eponymous template

Arafel via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jul 31 04:59:33 PDT 2017


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!!


More information about the Digitalmars-d-learn mailing list