templatized delegate

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon May 22 14:44:17 PDT 2017


On 05/22/2017 11:04 AM, Alex wrote:
> 3. Now the hard stuff comes. I want to templatize my delegate.
> struct A(alias dg)
> {
>      auto fun(T, U...)(T t, U u)
>      {
>          return dg!(T, U)(t, u);
>      }
> }
> 
> struct C
> {
>      A!dlgptr a;
> 
>      /* static? */ template dlgptr(T, U...)
>      {
>          /* static? */ void delegate(T, U) dlgptr;
>      }
> 
>      this(???)
>      {
>          ???
>      }
> 
>      void fun(T, U...)(T t, U args)
>      {
>          dlgptr!(T, U)(t, args);
>      }
> }
> 
> void main()
> {
>      auto dlg(T, U...)(T t, U u)
>      {
>          import std.stdio;
>          writeln(t, " ", u);
>      }
> 
>      auto c = C(???);
>      c.fun(5, "a"); // exception, obviously, as C is not initialized 
> properly
> 
>      A!dlg a;
>      a.fun(5, "a"); //Error: function test92.A!(dlg).A.fun!(int, 
> string).fun cannot get frame pointer to test92.main.dlg!(int, string).dlg
> }
> 
> Here, nothing works any more... I have no idea, what to pass to the 
> struct C, as a template is not an lvalue.

Not only is a template not an lvalue, it's not any kind of value at all. 
It doesn't have a type. You can't have a variable holding a template. 
You can't pass it as an argument.

But a template is a symbol. You can pass it in an alias parameter. So to 
pass dlg to C, you have to make C a template with an alias parameter, 
like A is.

> But even the direct 
> initialization of A doesn't work...
`A!dlg a;` works. Calling `fun` doesn't.

A.fun instantiates dlg, resulting in a delegate that should be able to 
access main's stuff. But it's not guaranteed that main is active when 
A.fun is called. You could have returned `a` from main before calling 
fun. For an actual delegate, a closure would be made in that case. But 
dlg isn't a delegate, it's a template. I guess it's not possible (or not 
feasible, or not implemented) to create a closure a template like this.

If you don't actually need dlg to access main's stuff, you can make it 
static. It's a function then and the delegate weirdness doesn't apply.

For another approach to your problem, maybe have a look at run-time 
variadic arguments:

https://dlang.org/spec/function.html#d_style_variadic_functions

With that kind of variadics, you're not dealing with a template. A 
(run-time) variadic delegate is an actual delegate, i.e. a value that 
can be passed around. But the variadic stuff is a bit weird to use, and 
probably affects performance.


More information about the Digitalmars-d-learn mailing list