Combining Delegate and Functions

Daniel Keep daniel.keep.lists at gmail.com
Tue Jun 30 10:23:18 PDT 2009



Jarrett Billingsley wrote:
> On Tue, Jun 30, 2009 at 11:38 AM, Jesse
> Phillips<jessekphillips at gmail.com> wrote:
>> So looking at a post on StackOverflow about D gatchas:
>> http://stackoverflow.com/questions/743319/why-isnt-the-d-language-picking-up/1059780#1059780
>>
>> "functions that form closures or are attached to objects (ie. methods) are not the same as regular functions, instead they are called delegates, and you must be aware of the differences."
>>
>> I seem to recall the distinction was going to be going away or minimized. Is this already done? Will it be going into D2?
> 
> Nothing's changed in that area.  Theoretically the compiler could
> implicitly convert function pointers to delegates by creating thunks.
> It shouldn't be *that* hard to implement..

Here's something I have in a project of mine.  I didn't come up with the
idea, but I forget who did.

Note that this is not generalised.  I started working on a general one,
but gave up when it proved too fiddly and difficult to correctly rebuild
a function's argument list.

/*
 * This is utterly evil, but also REALLY cool.
 *
 * What we do here is make a dummy struct, and give it a member
 * function.  The member function has a hidden argument (this).
 *
 * We then construct a delegate of the appropriate type, set its
 * funcptr to Wrap.call and its ptr to the function pointer.
 *
 * When dg is called, it is called as (dg.funcptr(dg.ptr, ...))
 * which is the same way the (this) argument of member functions
 * is passed.
 *
 * Thus, inside the member function, we can cast the this pointer
 * back to our function pointer and call it.
 */
struct Wrap
{
    void call(Context a, PullParserSlice b)
    {
        return (cast(void function(Context, PullParserSlice)) this)
            (a,b);
    }
}

ElementBinding.Handler dg;
Wrap wrap;

dg.ptr = handler;
dg.funcptr = cast(typeof(dg.funcptr)) &wrap.call;



More information about the Digitalmars-d mailing list