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:
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!
Thanks, this works well for my needs.