Function pointer to member function.

Chris Cain clcain at uncg.edu
Wed Oct 16 20:21:36 PDT 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!


More information about the Digitalmars-d-learn mailing list