Manually allocate delegate?

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jul 12 05:56:16 PDT 2015


On Sunday, 12 July 2015 at 08:38:01 UTC, Tofu Ninja wrote:
> Is it even possible?

Yes, though you need to use an entirely different approach for 
closures: make a struct.

Remember that delegates can come from local variable use or a 
`this` object being used and work the same way to the outside 
world. If it is local variables, the compiler emits the allocate 
calls and you have little control over it. If it comes from an 
object though, you have much more control: control over what is 
stored and control over how it is allocated.

The one notable thing you do NOT control is the delegate's 
lifetime. Once it becomes a delegate, it is interchangable with 
other delegates and is likely to be mixed in with other things 
and the recipient has no way of knowing where it came from. 
That's a feature in general, but it also means they can't know if 
they have to free() or release_reference() it.... if you need 
that, you might use a custom delegate type instead of the built 
in one.


Anyway though, just make a struct with the data you need to 
capture and a call method, then pass that around.


Before:

void foo() {
      int a;
      a = 10;
      // other code using a
      use_delegate( { a++; } );
}

After:

void foo() {
     static struct Captures {
       int a;
       void dg1() { a++; }
     }
     Captures captures;
     with(captures) {
        a = 10;
        // other code uing a
     }
     use_delegate(&captures.dg1);

     // WARNING: since captures is owned by this scope, 
use_delegate had better not hold on to it! But you could just as 
well have done Captures* captures = malloc(...) too.
}




So it is slightly more verbose and moves the inline delegate up 
to the struct (though if you got clever, you could probably 
change that too, like a delegate factory that takes a function 
and a this at the call point: dg( (_this) { _this.a++; }, 
captures); perhaps), but really the extra syntax overhead is 
small for real programs anyway.


And the clarity of what is and isn't captured might be worth it.


More information about the Digitalmars-d-learn mailing list