08-Jun-2013 03:21, Manu пишет:
So from my dconf talk, I detailed a nasty hack to handle member function
pointers in D.
My approach is not portable, so I'd like to see an expression formalised
in D, so this sort of interaction with C++ is possible, and also it may
be useful in D code directly.

I'm thinking something like this... Keen to hear thoughts.

My approach was this:
   void function(T _this, ...args...);

Explicit 'this' pointer; only works with ABI's that pass 'this' as the
first integer argument.

I decided to see how convenient can be a solution to auto-generate a thunk function that has exactly this signutre. In ABIs where this is passed as first parameters that shouldn't be much of overhead.

Here is my first try, it needs to handle overload sets but that could be added. Second point is perfect forwarding (there is forward in std.typecons, avoided for now). It may as well depend on compiler bugs but it looks nice and clean :)

module mem_fun;

import std.traits, std.stdio;

template memThunk(string call, T, U...)
    if(is(T == class))
{
    auto memThunk(T self, U args)
    {
        return mixin("self." ~ call~"(args)");
    }
}

struct memberFunc(T)
    if(is(T == class))
{
    static @property auto opDispatch(string fn)()
    {
        alias FnType = typeof(mixin("T."~fn));

        return &memThunk!(fn, T, ParameterTypeTuple!FnType);
    }
}

class A{
    void foo(int k)
    {
        writefln("Quack %d!\n", k);
    }
}

unittest
{
    void function (A, int) fun = memberFunc!A.foo;
    A a = new A();
    fun(a, 45); //prints Quack 45!
}


P.S. Having a way to express this-call calling convention explicitly could be very useful still especially taking into account recent enhancements to the extern(C++) support.

--
Dmitry Olshansky

Reply via email to