另一个答案指出了为什么您的代码不起作用。对于某些有限的情况,这是一个非常丑陋的解决方案。
typedef int (*ftwpt)(const char*, const struct stat*, int);
typedef boost::function<int(const char*, const struct stat*, int)> MyFTWFunction;
template <MyFTWFunction *callback>
class callback_binder {
public:
static int callbackThunk(const char *s, const struct stat *st, int i) {
return (*callback)(s, i);
}
};
extern void register_callback(callback_t f);
int random_func(const char *s, const struct stat *st, int i)
{
if (s && *s) {
return i;
} else {
return -1;
}
}
MyFTWFunction myfunc;
int main(int argc, const char *argv[])
{
myfunc = random_func;
register_callback(&callback_binder<&myfunc>::callbackThunk);
return 0;
}
使用指针作为模板参数的规则要求作为参数传入的指针是指向全局变量的指针。当然,该全局变量可以在匿名命名空间中声明。
这很丑陋,如果您想同时回调多个可能的 myMap 实例,则您需要尽可能多的全局 MyFTWFunction 变量,因为它可能同时存在 myMap 实例。大多数情况下,这会自动创建一个 thunk 函数,该函数使用全局变量的内容来填充缺失的参数。
这是一个不太灵活的版本,它对这种狭窄的情况做了大致相同的事情,这可能会使这里发生的事情更加明显:
#include <map>
#include <string>
using ::std::map;
using ::std::string;
typedef map<string, double*> myMap;
typedef int (*callback_t)(const char *, struct stat *st, int);
int myFunction(const char*, struct stat *st, int, myMap*);
template <myMap **map_ptr>
class myMap_binder {
public:
static int call_my_function(const char *s, struct stat *st, int i) {
return myFunction(s, st, i, *map_ptr);
}
};
extern void register_callback(callback_t f);
myMap *mainmap;
myMap *othermap;
int main(int argc, const char *argv[])
{
myMap m_map;
myMap m_map2;
mainmap = &m_map;
othermap = &m_map2;
register_callback(&myMap_binder<&mainmap>::call_my_function);
register_callback(&myMap_binder<&othermap>::call_my_function);
return 0;
}
如您所见,myMap_binder 是一个模板,它自动生成 thunk 函数,这些函数将全局变量的内容填充到对回调函数的调用中。