Templatized delegates

Christian Köstlin christian.koestlin at gmail.com
Tue May 31 22:34:41 UTC 2022


On 2022-05-31 23:15, 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`.
> 
> Here is code example:
> 
> ```d
> import std.stdio: writeln;
> 
> struct S
> {
>      // function that should be called from delegate
>      void doSomething(T)(T value) { value.writeln; }
> }
> 
> alias DG = void delegate (ref S s);
> 
> auto createDG(T)(T value)
> {
>      return delegate (ref S s) { s.doSomething(value); };
> }
> 
> struct R
> {
>      DG dg;
> 
>      this(int value)
>      {
>          dg = createDG(value);
>      }
> }
> 
> void main()
> {
>      auto r = R(5);
> 
>      S s;
>      r.dg(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?
> 
> I think ideal solution would be having templatized delegate `void 
> delegate (S)(ref S s)` and then call `r.dg!S(s)` but it's not available: 
> `alias DG = void delegate (S) (ref S s)` gives unclear `Error: function 
> declaration without return type. (Note that constructors are always 
> named 'this')` message.Would it help to not create the delegate in R's constructor, but feed 
the delegate into it (and create the delegate outside). This would also 
resemble your description (R is a delegate holder) more.




More information about the Digitalmars-d-learn mailing list