easily convert any method/function to a delegate

BCS BCS at pathlink.com
Wed Jul 18 15:40:22 PDT 2007


Daniel Korsgaard wrote:
> BCS wrote:
>>
>> R delegate(P) to_delegate(R, P...)(R function(P) fp)
>> {
>>     auto dg = delegate R(P p)
>>         {return (cast(R function(P))(cast(void*)this))(p);}
>>     dg.ptr = cast(void*)fp;
>>     return dg;
>> }
> 
> 
> Err.. where do you get that 'this' from?
> 

Aaahhh.... My Hat??

try this (totally bad form and all):

R delegate(P) to_delegate(R, P...)(R function(P) fp)
{
   struct S
   {
     R Go(P p)
     {
       return (cast(R function(P))(cast(void*)this))(p);
     }
   }
   return &(cast(S*)(cast(void*)fp)).Go;
}

void main()
{
   auto dg = to_delegate(&hello);
   dg(5);
}

int hello(int i)
{
   writef("hello world #%d\n", i);
   return 0;
}

(I actually tested this one)

> Anyways, my idea was to cut of the additional call. But if it really 
> have to be there, this is a lot cleaner:
> 
> R delegate(P) to_delegate(R, P...)(R function(P) fp)
> {
>     return delegate R(P p) { return fp(p); };
> }
> 
> .. hope you like it..

And you walk right into the other gotcha of delegates[1], returning a 
delegate to a nested function or anon delegate is *really bad*. It 
carries a context pointer to stack space that, after the function 
returns, is unusable. Random results result. The same goes for keeping 
them around by any other means.

[1] So many people miss it that there needs to be some size 24 blinking 
red bold notes next to a few sections of the spec about this.



More information about the Digitalmars-d mailing list