1

首先,我知道这在 C++ 中是不可能的。但我希望有人能说出我的问题的解决方法。我有一个代表数学函数的类:

class myClass:
{
private:
public:
    myClass() {};
    double value(double, double){ /* doing some complicated calculation here */} };
    double integrate { /*calc*/ return integral; };
}

integrate()我想创建一个引用value(). 该结构定义如下:

struct gsl_monte_function_struct {
    double (*f)(double * x_array, size_t dim, void * params);
    size_t dim;
    void * params;
};

(我需要这个结构来从 GSL 调用 Monte-Carlo 集成例程)

如前所述,我知道这在 C++ 中是被禁止的。但是有没有可能gsl_monte_function_struct与 myClass 的成员函数一起使用?如果无法myClass集成自身,是否可以gsl_monte_function_struct从类外部调用并value()作为参考?提前致谢!

4

2 回答 2

2

如果正确理解您,您需要一个指向myClass. 您可以通过将成员函数指针声明为:

double (myClass::*value)(double,double) 

稍后可以在实例上调用此函数:

(instance.*value)(x,y);

或者,您可以使用std::bind创建一个函数对象,该对象可以作为普通函数调用,而无需在调用后跟踪调用它的实例std::bind

auto& value = std::bind(myClass::value, instance);
// ....
value(x,y);
于 2013-10-30T10:40:49.467 回答
0

好的,到目前为止,我找到了两个解决方案:

1)(一般解决方案)使用一个抽象基类,它有一个指向当前实例的静态指针和一个调用派生类函数的静态函数。静态函数可以与函数指针一起使用。

例子:

struct gsl_monte{
   double (*f)(double y);
};

class myBase {
private:
  static myBase* instance;

public:
  myBase(){};
  static void setInstance(myBase* newOne);
  virtual double value(double x) =0;
  static double callValue(double x);//{return value(x);}
};

class myClass : public myBase {
   public:
      myClass(){};
      double value(double x) {  return x;  };
};

myBase* myBase::instance = new myClass();
double  myBase::callValue(double x){return instance->value(x);}
void myBase::setInstance(myBase* newOne){instance=newOne;};

double g(double xx) {return xx;};

int main(int argc, char** argv ){
   double x[2]; x[0]=1.3; x[1]=1.3;
   myClass* instance = new myClass();
   myBase::setInstance(instance);
   instance->value(3);
   std::cout << "Test " << myBase::callValue(5) << std::endl;
   gsl_monte T;
   T.f=&myBase::callValue;
   double (*f)(double y, void*) = &myBase::callValue;
}

2)(针对我的问题的解决方案)幸运的是,所需的函数接受一个参数指针,我可以用它来传递当前对象:

#include <iostream>
#include <functional>
using namespace std::placeholders;

struct gsl_monte{
   double (*f)(double y, void*);
};

class myClass {
   public:
      myClass(){};
      double value(double x) {  return x;  };
};

double valueTT(double x, void* param) {  return static_cast<myClass*>(param)->value(x);  };

int main(int argc, char** argv ){
   double x[2]; x[0]=1.3; x[1]=1.3;
   myClass* instance = new myClass();
   instance->value(3);
   gsl_monte T;
   T.f=&valueTT;
   double (*f)(double y, void*) = &valueTT;
}
于 2013-10-31T09:02:45.170 回答