DMD 0.174 release
Reiner Pope
reiner.pope at REMOVE.THIS.gmail.com
Wed Nov 15 15:40:26 PST 2006
Jarrett Billingsley wrote:
> "Kirk McDonald" <kirklin.mcdonald at gmail.com> wrote in message
> news:ejeepp$15n1$1 at digitaldaemon.com...
>> Jarrett Billingsley wrote:
>>> A few questions:
>>>
>>> 1) For the delegate .funcptr property, would it be possible for it to
>>> include the context pointer as the first parameter? Currently the
>>> .funcptr allows us to get the type / call signature of the delegate but
>>> it's not possible to actually use the resulting function as there is no
>>> way to pass it the context short of dipping into ASM..
>>>
>> Not so: Walter added a .ptr property to delegates in 0.168. Between that
>> and .funcptr, you've got all you need to mess with delegates right there.
>
> Well even with the context pointer, how do you propose passing it to the
> resulting func pointer? The context is passed implicitly as the first
> parameter to any delegate, and without that first parameter in the parameter
> list, you can't pass the context. So
>
> class A { void fork(int x) { } }
>
> A a = new A();
> auto dg = &a.fork;
> auto fp = dg.funcptr;
>
> fp(3); // access violation
>
> What's worse is that because the parameter list doesn't include the context,
> trying to call fp will result in all the arguments being shifted down a
> position from where they should be, i.e. 3 will now be in the 'this' slot,
> and nothing useful will be in the 'x' slot. :S So you _have_ to use ASM to
> call that func pointer, or maybe use some template trickery to create a
> pointer to the function with an extra first param.
>
>
I'm not sure if this is what you want, but here's a cast-free 'call'
function:
import std.stdio : writefln;
class A {
int a_m;
this(int a)
{
this.a_m = a;
}
void fork(int b)
{
writefln(a_m,b);
}
}
void main()
{
A a = new A(1);
A b = new A(2);
auto dg = &a.fork;
auto fp = dg.funcptr;
call(fp, a, 3); // Prints 13
call(fp, b, 3); // Prints 23
}
B call(A, B, Params...)(B function (Params) fp, A a, Params p)
{
B delegate(Params) dg;
dg.funcptr = fp;
dg.ptr = a;
return dg(p);
}
More information about the Digitalmars-d-announce
mailing list