如何将对象
eval
的非静态成员函数Problem1 obj
传递给对象Solver solver
?
#include<iostream>
#include<functional>
// non-templated class
struct Solver{
std::function<void(double&, double&)>* f;
double solve(){
double y,x=1;
for(long int i=0;i<10000;++i){
(*f)(y,x); (*f)(x,y);
}
return y;
}
};
// non-static class; unknown at implementation time of Solver
struct Problem1{
double p;
void eval(double& y, double& x){
y = x*x - p;
}
};
int main(){
Problem1 obj;
Solver solver;
solver.f = &(obj.eval); // pass non-static member function
solver.solve();
}
由于应使用一个求解器来解决各种问题类的许多不同实例,因此我不想使用模板。由于解决一个问题对象可能需要多次调用
eval
,由于 C++ 中虚拟类的开销和缓慢的声誉,我不敢使用 VirtualProblem
类的虚拟继承。这在这里重要吗?我该怎么办?
这不是
std::function
的工作原理。
首先它不应该是一个指针。您不能将指向非静态成员函数的指针分配给它(尤其是它的指针)。而且你不能那样使用非静态成员函数。
为了解决您的问题,首先让
f
成为一个非指针对象:
struct Solver{
std::function<void(double&, double&)> f;
double solve(){
double y,x=1;
for(long int i=0;i<10000;++i){
f(y,x); f(x,y);
}
return y;
}
};
然后我们可以使用 lambda 在正确的对象上调用正确的函数:
solver.f = [&obj](double& a, double& b)
{
obj.eval(a, b);
};
std::bind
将函数与其对象及其参数绑定:
solver.f = std::bind(obj, &Problem1::eval, std::placeholders::_1, std::placeholders::_2); // pass non-static member function
但请注意,lambda 变体是通常推荐的方式。
另一方面,如果你想从函数返回一个值,实际上是
return
一个值。
我想,你可以使用'std::bind'