他の回答は、コードが機能しない理由を示しています。ここでは、特定の限られた状況のために、ある種のことが起こる、本当に醜い解決策があります。
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の同時インスタンスとして使用する必要があります。主に、グローバル変数の内容を使用して不足しているパラメータを埋めるサンク関数の作成を自動化します。ここで
はここで何が起こっているか、それがより明白にすることがあり、この狭い場合のために、ほぼ同じことをしLOTあまり柔軟性のあるバージョンである:あなたがmyMap_binder見ることができるように
#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;
}
テンプレートですグローバル変数の内容に含まれるサンク関数をコールバック関数の呼び出しに自動生成します。
@Konradあなたのコードが失敗した理由も説明しています:ここで読むhttp://stackoverflow.com/questions/282372/demote-boostfunction-to-a-plain-function-pointer/512233 #512233 –
@HazyBlueDot - この質問はCではなく、Cであり、正しくはタグ付けしてください。 –