lundi 25 décembre 2017

Passing member function pointers through templates

I used this delegate implementation as a starting point and updated it to use varidadic templates.

I also tried to create a createCallback-function which would create a Callback object in one instance, but got a compile error which I do not fully understand.

A very basic example would be this (I removed the Callback class for clarity):

template<typename R, class T, typename ...P>
class MemberCallbackFactory
{
public:        
    template<R (T::*Func)(P...)>
    inline static void Bind(T* o)
    {
     //
    }
};

template<typename R, class T, typename ...P>
inline void
createCallback(T* obj, R (T::*Func)(P...))
{
    MemberCallbackFactory<R, T, P...>().template Bind<Func>(obj);
}

class Test
{
public:
    void doSomething(int val)
    {
        //
    }
};

int main()
{
    Test t;
    // Works:
    MemberCallbackFactory<void, Test, int>().Bind<&Test::doSomething>(&t);
    // Produces compile error:
    createCallback(&t, &Test::doSomething);
    return 0;
}

Compiling this example with gcc4.9.2 using C++11 returns:

test2.cpp:11:28: note:   template argument deduction/substitution failed:
test2.cpp:21:9: error: ‘func’ is not a valid template argument for type ‘void (Test::*)(int)’
        MemberCallbackFactory<R, T, P...>().template Bind<func>(obj);
        ^
test2.cpp:21:9: error: it must be a pointer-to-member of the form ‘&X::Y’
test2.cpp:21:9: error: could not convert template argument ‘func’ to ‘void (Test::*)(int)’

So if I pass &Test::doSomething to createCallback as the Func parameter why can't I forward it to the Bind method? Shouldn't it be of correct type?

Aucun commentaire:

Enregistrer un commentaire