在下面的代码中,我想不出将成员函数传递给通用根查找器的方法。
#include <stdio.h>
double OneDimBisector(double (*fun)(float), float a, float b, float tol){
double val;
val = (*fun)(0.5*(b-a)); // actually: do proper bisection
return val;
}
class EOS {
public:
double S_array[10][10]; // actually: filled by constructor
double S(double T, double P);
double T_PS(double P, double S);
double functForT_PS(double T);
double (EOS::*pfunctForT_PS)(double);
double Sseek, Pseek;
};
double EOS::S(double T, double P){
double val = T+P; // actually: interpolate in S_array
return val;
}
double EOS::functForT_PS(double T){
return S(T,Pseek)-Sseek;
}
// Find T from P and S (T is invertible), assuming the intervals are ok
double EOS::T_PS(double P, double S0){
double Tmin = 2., Tmax = 7., T1, tol=1e-8;
pfunctForT_PS = &EOS::functForT_PS;
Sseek = S0;
Pseek = P;
printf("\n %f\n", (*this.*pfunctForT_PS)(4.)); // no problem
T1 = OneDimBisector(pfunctForT_PS, Tmin, Tmax, tol); // wrong type for pfunctForT_PS
return T1;
}
int main() {
double P=3., S=8;
EOS myEOS;
printf("\n %f %f %f\n",P,S,myEOS.T_PS(P,S));
}
我不想让 root-finder 成为一个成员,因为它不是特定于这个类的,而且让一切都成为 static
的解决方案似乎很不优雅。有人会有想法吗?这种情况应该很常见,但我没有找到相关的帖子,我也能理解。
谢谢!
编辑: 实际上,我还想问:除了我所做的之外,是否有适当的、线程安全的方法来设置 Pseek
变量?澄清一下:我正在对二维函数进行一维求根,但固定了两个参数之一。
最佳答案
一种方法是更改根查找器的签名(添加 #include <functional>
):
double OneDimBisector(std::function<double(float)> f, float a, float b, float tol);
然后用 bind
调用它:
T1 = OneDimBisector(std::bind(pfunctForT_PS, this, std::placeholders::_1),
Tmin, Tmax, tol);
这会带来一定的开销。如果你不介意有很多重复代码,你可以把这个函数做成一个模板:
template <typename Func>
double OneDimBisector(Func f, float a, float b, float tol);
您以相同的方式调用它,但每次您有一个新的函数类型时,都会在您的编译中创建一个新的模板实例。
“传统”解决方案是拥有一个接受额外实例参数的自由(或静态)函数。
更新:“传统解决方案”:
double OneDimBisector(double(*f)(float, void *), void * data, ...);
double EOSBisect(float f, void * data)
{
EOS * e = static_cast<EOS *>(data); // very "traditional"
return e->functorForT_PS(f);
}
用法:T1 = OneDimBisector(EOSBisect, this, Tmin, Tmax, tol);
关于c++ - 将成员函数指针传递给无类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8852472/