もう1つの答えは、コードが機能しない理由を示しています。これは、特定の限られた状況に対して、ある種の、ある種の、本当に醜い解決策です。
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のいくつかの可能なインスタンスを同時にコールバックしたい場合は、myMapの可能な限り多くのグローバルMyFTWFunction変数が必要になります。ほとんどの場合、これにより、グローバル変数の内容を使用して欠落しているパラメーターを埋めるサンク関数の作成が自動化されます。
これは、柔軟性が非常に低いバージョンであり、この狭いケースでもほぼ同じことを行い、ここで何が起こっているのかをより明確にする可能性があります。
#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は、グローバル変数の内容をコールバック関数の呼び出しに詰め込むサンク関数を自動生成するテンプレートです。