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.