1

I am using the variadic call pattern shown here. It works fine for ordinary C functions. But I want to use it with a member function and a tuple that explicitly has an instance pointer as the first argument.

I tried something like this:

template<typename Ret, typename C, typename...Args>
int methodWrapper(const string& name, Ret (C::*func)(Args...), lua_State* L)
{
    return wrap<Ret,C*,Args...>::wrapFunc(name, func, L);
}

But it fails to convert the pointer type:

cannot initialize a parameter of type 'void (*)(Object *, float, float)' with an lvalue of type 'void (Object::*)(float, float)'

In this case, the wrap function is templated, so the type of the pointer has to match exactly.

template<typename Ret, typename...Args>
struct wrap{
    static int wrapFunc(const string& name, Ret (*func)(Args...), lua_State* L)
    {
        ...
    }
};

How to I explicitly convert a member function pointer into an ordinary function pointer that takes the this pointer as its first argument?

EDIT: for those that have linked me to this question, it is not the same. I do not have to pass a plain C function pointer to an existing API with a specific interface. And I am not trying to bind a member function to a specific object. This question also does not deal with variadic call or tuples.

7
  • Possible duplicate of Convert C++ function pointer to c function pointer Commented Dec 2, 2015 at 16:27
  • Or stackoverflow.com/questions/19808054/…, if you prefer Commented Dec 2, 2015 at 16:28
  • And maybe stackoverflow.com/questions/4210710/… Commented Dec 2, 2015 at 16:28
  • You should know that lua_CFunction has type extern "C" int (*) (lua_State *L). That you can pass int (*)(lua_State *L) instead is a bug in nearly every compiler and isn't standard conformant. Commented Dec 2, 2015 at 16:31
  • What about creating a lambda and passing that in? What does wrapFunc do with the function it receives? Commented Dec 2, 2015 at 16:40

1 Answer 1

0

std::mem_fn does this.

In order to make the template match: I had to explicitly declare the args tuple as a Class pointer followed by the parameter pack:

template<typename C, typename...Args>
struct wrapMethod<void,C,Args...>{
    static int wrap(const string& name, void (C::*func)(Args...), lua_State* L)
    {
        tuple<C*, Args...> args = cargs<C*,Args...>::getCArgs(L, name);

        //Return type (first template parameter) cannot be inferred.
        variadic_call<void>(mem_fn(func), args);

        return 0;
    }
};
Sign up to request clarification or add additional context in comments.

1 Comment

Actually, it doesn't. It just converts a member-function-pointer into a callable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.