. Böylece, (C++ stili) işlev nesnelerini (functor) kullanamazsınız, ancak işaretçiyi gerçek bir işleve sağlamalıdır ve kişi, bir kişiyi, functor'ı benzer şekilde aynı şekilde oluşturamaz.
// from some gsl header:
extern "C" {
typedef double gsl_function(double, void*);
// calls func(arg,data_passed_to_func)
double gsl_api_function(gsl_function*func, void*data_passed_to_func);
}
// in your source code
double(*target_func)(double); // global variable can be hidden in some namespace
extern "C" {
double funtion_calling_target(double, void*)
}
double funtion_calling_target(double arg, void*)
{
return target_func(arg);
}
bool test(double x, double(*func)(double))
{
target_func = func;
return x < gsl_api_function(function_calling_target,0);
}
(gizleme target_func
olarak statik üyesi:
Aslında küresel değişkeni çağıran belirli gsl_function
tanımlamak daha sonra gerçek fonksiyonunu (a_squared
) depolamak ve küresel bir değişkeni kullanabilirsiniz ( tavsiye edilmez) bazı sınıfların atkins'in cevabı gibi, hala global bir değişken gerektirir). Bu çalışır, ancak zayıftır, çünkü 1) bu mekanizma global bir değişken gerektirir ve 2) sadece bir hedef fonksiyonun herhangi bir zamanda kullanılmasına izin verir (bunu sağlamak zor olabilir).
(Önerilen) Ancak, başka bir işlev işaretçisini argüman olarak alan ve bunu veri öğesi olarak geçiren özel bir işlev tanımlayabilirsiniz. Bu, aslında gsl_function
'un tasarımının ardındaki fikirdi: void*
, işlevin gerektirebileceği herhangi bir yardımcı veriyi gösterebilir. Bu veriler başka bir işlev olabilir.
// your header
extern "C" {
double function_of_double(double, void*);
}
inline double function_of_double(double arg, void*func)
{
typedef double(*func_of_double)(double);
return reinterpret_cast<func_of_double>(func)(arg);
}
// your application
bool test(double x, double(*func)(double))
{
return x < gsl_api_function(function_of_double, (void*)(func));
}
Bu, genel bir değişken gerektirmez ve istediğiniz kadar çok sayıda eş zamanlı işlevle çalışır. Tabii ki, burada, her mantıklı C++ programcısı olan bir şey olan void*
ile uğraşırken, void*
manipülasyonlarına dayanan korkunç bir C kütüphanesi kullanıyorsunuz.
Bu niçin 'C++' olarak etiketlenmiş? GSL bir C kütüphanesidir ve bir C tipi fonksiyon göstericisine ihtiyaç duyar. Bu yüzden C++ işlevselliğine dayalı herhangi bir çözüm (std :: bind gibi) başarısız olur. – Walter
Küçük bir sarmalayıcı @Walter - kullanıyorsanız ve bu lambda ve 'std :: bind' içerir C++ işlevselliği başarısız. Benim cevabım –