Member function as parameter for a function template

Viewed 122

I want to register callback functions, and store them in a vector to call them. It should also be allowed to use member functions as callback functions.

My initial was approach was using <functional> in the following way:

#include <functional>
#include <vector>
#include <iostream>


std::vector<std::function<void()>> functions;

struct Foo {
    void Bar() {
        std::cout << "Hello" << std::endl;
    }
};

template<class T>
void Register( T* obj, std::function<void(T*)> function ) {
    functions.push_back( std::bind( function, obj ) );
}

void main(){
    Foo foo;
    Register(&foo, &Foo::Bar);
}

This doesn't work since the compiler cannot deduce the parameter type. It only works if I specify the type explicitly: Register<Foo>(&foo, &Foo::Bar);. This is not what I wanted, so I tried using the old function pointers:

template<class T>
void Register( T* obj, void(T::* function)() ) {
    functions.push_back( std::bind( function, obj ) );
}

And it worked. Since I dislike this form of function pointers I made a type for Memberfunction pointers:

template<class Owner>
using Memberfunction = void( Owner::* )();

template<class T>
void Register( T* obj, Memberfunction<T> function ) {
    functions.push_back( std::bind( function, obj ) );
}

This worked just fine. But now I wanted to support functions with one single parameter, since I didn't want to specify a Memberfunction for each parameter type I wanted to again use templates.

template<class Owner, class Param>
using Memberfunction = void( Owner::* )( Param );

template<class T>
void Register( T* obj, Memberfunction<T,float> function ) {
    using namespace std::placeholders;
    functions.push_back( std::bind( function, obj, _1 ) );
}

This worked good so far, but I didn't want to have to to specify a member function for one or no parameter, so I wanted to use void as second parameter of Memberfunction, but this lead to an internal compiler error, so I guess this doesn't work.

Interestingly Memberfunction<Foo,void> bar = &Foo::Bar; lead to the following error:

cannot convert from 'void (__thiscall Foo::* )(void)' to 'void (__thiscall Foo::* )(void)'

So now to my questions:

Is it somehow possible to use std::function for this?

If this doesn't work can I avoid having to specify at least two member function types?

Thanks in advance for your help.

2 Answers
Related