digitalmars.D.learn - Function pointer to member function.
- TheFlyingFiddle (19/19) Oct 16 2013 I would like to get access to a member function pointer. Taking
- Chris Cain (54/59) Oct 16 2013 Well, it's certainly possible. If you were to do this:
- TheFlyingFiddle (2/65) Oct 17 2013 Thanks, this works well for my needs.
I would like to get access to a member function pointer. Taking the this* as the first argument. class Foo { void bar(int a) { //do something awesome } } unittest { Foo a = new Foo(); Foo b = new Foo(); auto fp = getFP!(Foo.bar); fp(a, 1); //Basically calls a.foo(1) fp(b, 1); //Basically calls b.foo(1) } How should i implement getFP above? Is it even possible?
Oct 16 2013
On Thursday, 17 October 2013 at 01:17:21 UTC, TheFlyingFiddle wrote:I would like to get access to a member function pointer. Taking the this* as the first argument. ...snip... How should i implement getFP above? Is it even possible?Well, it's certainly possible. If you were to do this: ``` delegate void(int) dg = &a.bar; dg(1); ``` then you'd see the behavior you're looking for. Basically the class reference is stored in dg.ptr and the function is in dg.funcptr. With that in mind, I whipped this up: ``` import std.stdio; class Foo { char c; this() { c = 'a'; } this(char _c) { c = _c; } void bar(int i) { writeln("i = ", i, " c = ", c); } } import std.traits; //ParentOf!S is pseudocode representing __traits(parent, S) //ReturnType!S function(ParentOf!S, ParameterTypeTuple!S) auto getFP(alias S)() if(isSomeFunction!S) { mixin("alias Parent = " ~ __traits(parent, S).stringof ~ ";"); return (Parent r, ParameterTypeTuple!S t) { ReturnType!S delegate(ParameterTypeTuple!S) dg; dg.funcptr = &S; dg.ptr = cast(void*) r; return dg(t); }; } void main() { Foo a = new Foo(); Foo b = new Foo('b'); auto fp = getFP!(Foo.bar); fp(a, 1); fp(b, 2); } ``` Now one thing to note is that I'm not confident it's bug-free. It does work in this test case, but I couldn't use __traits(parent, S) as a type, so I used a mixin to kind of force it to work. So I'm not fully sure whether it will work in all cases, but if someone else has some improvements, that's fine. Another thing: I didn't spend too much time on the template constraint. "isSomeFunction" is almost certainly too permissive. I just threw it together and I haven't coded in D for a while. I hope this helped!
Oct 16 2013
On Thursday, 17 October 2013 at 03:21:38 UTC, Chris Cain wrote:On Thursday, 17 October 2013 at 01:17:21 UTC, TheFlyingFiddle wrote:Thanks, this works well for my needs.I would like to get access to a member function pointer. Taking the this* as the first argument. ...snip... How should i implement getFP above? Is it even possible?Well, it's certainly possible. If you were to do this: ``` delegate void(int) dg = &a.bar; dg(1); ``` then you'd see the behavior you're looking for. Basically the class reference is stored in dg.ptr and the function is in dg.funcptr. With that in mind, I whipped this up: ``` import std.stdio; class Foo { char c; this() { c = 'a'; } this(char _c) { c = _c; } void bar(int i) { writeln("i = ", i, " c = ", c); } } import std.traits; //ParentOf!S is pseudocode representing __traits(parent, S) //ReturnType!S function(ParentOf!S, ParameterTypeTuple!S) auto getFP(alias S)() if(isSomeFunction!S) { mixin("alias Parent = " ~ __traits(parent, S).stringof ~ ";"); return (Parent r, ParameterTypeTuple!S t) { ReturnType!S delegate(ParameterTypeTuple!S) dg; dg.funcptr = &S; dg.ptr = cast(void*) r; return dg(t); }; } void main() { Foo a = new Foo(); Foo b = new Foo('b'); auto fp = getFP!(Foo.bar); fp(a, 1); fp(b, 2); } ``` Now one thing to note is that I'm not confident it's bug-free. It does work in this test case, but I couldn't use __traits(parent, S) as a type, so I used a mixin to kind of force it to work. So I'm not fully sure whether it will work in all cases, but if someone else has some improvements, that's fine. Another thing: I didn't spend too much time on the template constraint. "isSomeFunction" is almost certainly too permissive. I just threw it together and I haven't coded in D for a while. I hope this helped!
Oct 17 2013