@Snps 答案很完美!但正如@DXM 提到的,它只能容纳一个回调。我对其进行了一些改进,现在它可以保留许多相同类型的回调。这有点奇怪,但效果很好:
#include <type_traits>
template<typename T>
struct ActualType {
typedef T type;
};
template<typename T>
struct ActualType<T*> {
typedef typename ActualType<T>::type type;
};
template<typename T, unsigned int n,typename CallerType>
struct Callback;
template<typename Ret, typename ... Params, unsigned int n,typename CallerType>
struct Callback<Ret(Params...), n,CallerType> {
typedef Ret (*ret_cb)(Params...);
template<typename ... Args>
static Ret callback(Args ... args) {
func(args...);
}
static ret_cb getCallback(std::function<Ret(Params...)> fn) {
func = fn;
return static_cast<ret_cb>(Callback<Ret(Params...), n,CallerType>::callback);
}
static std::function<Ret(Params...)> func;
};
template<typename Ret, typename ... Params, unsigned int n,typename CallerType>
std::function<Ret(Params...)> Callback<Ret(Params...), n,CallerType>::func;
#define GETCB(ptrtype,callertype) Callback<ActualType<ptrtype>::type,__COUNTER__,callertype>::getCallback
现在你可以做这样的事情:
typedef void (cb_type)(uint8_t, uint8_t);
class testfunc {
public:
void test(int x) {
std::cout << "in testfunc.test " <<x<< std::endl;
}
void test1(int x) {
std::cout << "in testfunc.test1 " <<x<< std::endl;
}
};
cb_type* f = GETCB(cb_type, testfunc)(std::bind(&testfunc::test, tf, std::placeholders::_2));
cb_type* f1 = GETCB(cb_type, testfunc)(
std::bind(&testfunc::test1, tf, std::placeholders::_2));
f(5, 4);
f1(5, 7);