I am trying to store a function pointer in a class in a generic way(works with all member/non-member/global functions).

In the main() function below, there are two cases(A, B).

If case B is commented out, this code complies/runs fine. Otherwise, I get these errors, and the compiler pointing at "dg.funcptr = &T[0];" in TestClas.invoke(void*).

Error: this for instanceMethod needs to be type TestClass not type main.FuncPtr!(instanceMethod).FuncPtr Error: cannot implicitly convert expression (&(__error).instanceMethod) of type void delegate() to void function() Error: template instance main.FuncPtr!(instanceMethod) error instantiating


Am I missing something here or is this a bug?

class TestClass {
    void instanceMethod() {
        writeln("Instance Method!");
    }

    static void staticMethod() {
        writeln("Static Method!");
    }
}

void GlobalMethod() {
    writeln("Global Method!");
}

void invokeFunction(T...)(void *instance){
    alias typeof(T[0])                       method_type;
    alias ReturnType!method_type             return_type;
    alias ParameterTypeTuple!method_type     param_types;
    alias return_type delegate(param_types)  delegate_type;

    delegate_type dg;
    dg.ptr = instance;
    dg.funcptr = &T[0];
    dg();
}

class FuncPtr(T...) {
    void invoke(void *instance) {
        alias typeof(T[0])                       method_type;
        alias ReturnType!method_type             return_type;
        alias ParameterTypeTuple!method_type     param_types;
        alias return_type delegate(param_types)  delegate_type;

        delegate_type dg;
        dg.ptr = instance;
        dg.funcptr = &T[0];
        dg();
    }
}

void main() {
    TestClass testClass = new TestClass();

    // case A
invokeFunction!(TestClass.instanceMethod)(cast(void*)testClass);
    invokeFunction!(TestClass.staticMethod)(null);
    invokeFunction!(GlobalMethod)(null);

    // case B
    auto fp1 = new FuncPtr!(TestClass.instanceMethod);
    auto fp2 = new FuncPtr!(TestClass.staticMethod);
    auto fp3 = new FuncPtr!(GlobalMethod);

    fp1.invoke(cast(void*)testClass);
    fp2.invoke(null);
    fp3.invoke(null);
}

Reply via email to