Search code examples
c++templatesvariadic-templatespointer-to-member

Templated method pointer - can't match pointer for function argument


I am making a method pointer wrapper like this:

template<typename OBJECT, typename... ARGS>
method_wrapper<ARGS...> _getWrapper(OBJECT* object, void (OBJECT::*method)(ARGS...))
{
    //irrelevant
}

The problem is right at the calling of _getWrapper:

class TestClass
{

    void TestMethod(int a, float b, bool c)
    {
        std::cout<<a<<std::endl;
        std::cout<<b<<std::endl;
        std::cout<<c<<std::endl;
    }
};

int main()
{
TestClass testObj;

method_wrapper<int, float, bool> wrap = _getWrapper<int, float, bool>(&testObj, TestClass::TestMethod);

wrap.callInternal(1000, 3.14, true);

//...

system("pause");

return 0;
}

Not matter in what way I try to pass the arguments in _getWrapper, it still tells me:

no instance of overloaded function matches the argument list

Doesn't OBJECT::*method match TestClass::TestMethod directly? I also tried &TestClass::TestMethod, doesn't match either.


Solution

  • You're specifying the template arguments explicitly when invoking _getWrapper, and the first one is specifed as int for template parameter OBJECT, which is wrong. Because member pointers can't refer into non-class type.

    Change

    _getWrapper<int, float, bool>(&testObj, TestClass::TestMethod)
    

    to

    _getWrapper<TestClass, int, float, bool>(&testObj, &TestClass::TestMethod)
    //          ~~~~~~~~~~
    

    Note you can just rely on template type deduction, e.g.

    _getWrapper(&testObj, &TestClass::TestMethod)
    

    BTW: For taking address from members you should always use & for it.
    BTW: I suppose TestClass::TestMethod is public.