easily convert any method/function to a delegate

Daniel Korsgaard d__s__k at hotmail.com
Wed Jul 18 15:43:35 PDT 2007


BCS wrote:
> 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)
> 

Looks promising :)

>> 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.

you are soo right.. believe it or not, but i was actually on my way to
correct it, as it just popped op that the delegate context could/would
dissaper right after the return.. :'(



More information about the Digitalmars-d mailing list