类成员函数作为函数指针的实参输入
问题描述
在nlopt中常用到加不等式约束或者等式约束,此时需要输入关于参变量的表达式函数inconstraint,利用的是函数指针将表达式函数传递其中。但是类成员函数inconstraint不能被全局函数nlopt_xx读入,会报错“实参与形参类型不兼辅”,利用function和bind生成可调用对象,报错没有适当的转换函数
nlopt_add_inequality_constraint(opter, inconstraint, NULL, tol);
global = std::bind(&Class::inconstraint, this, std::placeholders::_1, std::placeholders::_2);
// 不等式约束;
nlopt_add_inequality_constraint(opter, global , NULL, tol);//报错没有适当的转换函数
希望不生成对象的情况下,调用一个类成员函数作为一个函数指针的实参,一般情况下,只有静态成员函数才能作为函数指针的实参,静态成员函数有地址。例如希望通过全局函数callFunc,此处将callFunc类比为nlopt中加约束的函数,用其调用类 MemberFuncClass中的inconstraint函数,调用方式是通过函数指针的形式。请教了师兄给了如下方法
void callFunc(double (*pf)(double, const double*))
{
double d = 1.0;
double* pd = nullptr;
std::cout << pf(d, pd) << std::endl;
return;
}
类MemberFuncClass
// An highlighted block
class MemberFuncClass
{
public:
double inconstraint(double d, const double* cd)
{
return memberD + d;
}
};
在类中添加如下函数和成员,通过一个静态成员函数staticlFuncAdapter作为媒介,以及静态函数的return调用,实现了函数传递,直接通过bind生成的函数对象staticlFuncAdapter不能直接被传递到calllFunc中。
void testCallFunc()
{
staticlFuncAdapter = std::bind(&MemberFuncClass::inconstraint, this, std::placeholders::_1, std::placeholders::_2);
callFunc(inconstraintHelper);
}
double memberD;
private:
static double inconstraintHelper(double d, const double* cd)
{
return staticlFuncAdapter(d, cd);
}
static std::function<double(double, const double*)> staticlFuncAdapter;
int main()
{
MemberFuncClass m;
m.memberD = 10.0;
m.testCallFunc();
}
此外,另一个师兄也给出了方法,在类中创建一个本类的对象,并通过静态成员函数调用静态成员对象的非静态成员函数(约束函数)
double testCallFunc()
{
memberFuncClass = this;
callFunc(inconstraint_help);
return 0;
}
double memberD;
static MemberFuncClass* memberFuncClass;
private:
static double inconstraint_help(double d, const double* cd)
{
return memberFuncClass->inconstraint(d, cd);
}
记得类外初始化
MemberFuncClass* MemberFuncClass::memberFuncClass = nullptr;
第一次接触函数指针,也学习了不少发现bind function库的内容,发现他们都需要创建对象才能使用,而这里师兄巧妙的利用return化解的困难,值得我多多学习。仅此记录我的菜鸟计算机之路