Templatized delegates

Paul Backus snarwin at gmail.com
Tue May 31 21:53:17 UTC 2022


On Tuesday, 31 May 2022 at 21:15:24 UTC, Andrey Zherikov wrote:
> I have tightly coupled code which I'd like to decouple but I'm 
> a bit stuck.
> For simplicity, I reduced the amount of code to something 
> simple to understand. So I have a struct `S` that has templated 
> member function that does something. On the other side I have 
> delegate holder `R` - this delegate takes `S` object as an 
> argument and calls that function. My goal is to remove 
> dependency from `R` to `S`.
[...]
> An obvious way is to add a type template parameter to `R`, `DG` 
> and `createDG` but I would like to avoid this. Is there another 
> way to do so?

If you want compile-time polymorphism, three's no other way. If 
you're ok with runtime polymorphism, you could replace S with 
something like an interface or a sum type. For example:

```d
import std.stdio;

struct S
{
     // function that should be called from delegate
     void doSomething(T)(T value) { value.writeln; }
}

interface I
{
     void doSomething(int value);
}

class Adapter : I
{
     S s;
     this(S s) { this.s = s; }
     void doSomething(int value) { s.doSomething(value); }
}

alias DG = void delegate (I i);

auto createDG(int value)
{
     return delegate (I i) { i.doSomething(value); };
}

struct R
{
     DG dg;

     this(int value)
     {
         dg = createDG(value);
     }
}

void main()
{
     auto r = R(5);

     S s;
     r.dg(new Adapter(s));
}
```


More information about the Digitalmars-d-learn mailing list