c++ - 将成员函数指针传递给无类函数

标签 c++ argument-passing pointer-to-member

在下面的代码中,我想不出将成员函数传递给通用根查找器的方法。

#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/

相关文章:

c++ - 用C++枚举安装在windows上的应用程序

c++ - 重构所有类通用的方法

c++ - 打印字节的正确类型转换

c++ - 我可以将 std::atomic<int64> 放置在共享内存中并期望原子操作吗?

java - 在主循环的函数参数中找不到符号?

python - 在装饰器中定义函数

c - 将传递给程序的参数转换为 long double 变量的正确方法是什么?

C++ 指向具有匹配函数签名的任何类的成员函数的指针

c++ - 通过operator()调用类模板成员函数指针

c++ - 指向成员变量的多态指针