I would like to create a template callback class which can call either a static function or a class method, but I'm struggling hard.
I have the following class:
template<class R, class ... Args> class Callback;
template<class R, class ... Args> class Callback<R(Args...)> {
protected:
typedef R (*func_t)(Args...);
func_t f;
public:
/**
* Constructor from function
* @param fIn Input function
*/
Callback(const func_t &fIn) :
f(fIn) {
}
virtual ~Callback() {
}
/**
* Call operator
* @param args Arguments for function call
* @return Return of function
*/
inline R operator()(Args ... args) const {
return f(args...);
}
};
When I create a callback object from a static function or a lambda it works perfectly:
int add(int x, int y, int z) {
return x + y + z;
}
int main() {
typedef Callback<int(int, int, int)> cb_t;
cb_t addCb(add);
std::cout << addCb(2, 3, 4) << std::endl;
cb_t mulCb([](int x, int y, int z){return x * y * z;});
std::cout << mulCb(2, 3, 4) << std::endl;
return 0;
}
which displays:
9
24
Now I want to make it available to class methods using std::bind. I tried adding a constructor in Callback class:
template<typename T> Callback(T &&obj, R (T::*fIn)(Args...)) : f(std::bind(fIn,obj)){
}
And new main:
class foo {
public:
foo() : x(12) {};
int myFunc(int a, int b, int c) {
this->x = (2 + a) * (b + c);
return this->x;
}
int getX() {
return x;
}
protected:
int x;
};
int main() {
typedef Callback<int(int, int, int)> cb_t;
foo fooInstance;
cb_t fooMethodCb(&fooInstance, &foo::myFunc);
std::cout << fooMethodCb(2, 3, 4) << std::endl;
return 0;
}
which doesn't compile. I get an error with constructor:
./src/callback.h: note: candidate template ignored: deduced conflicting types for parameter 'T' ('foo *' vs. 'foo')
which seems normal, but I just can't find the good usage of T in my constructor to get it working.
Thanks for your help!
Note: I need it to be c++11-compatible.
Aucun commentaire:
Enregistrer un commentaire