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 からモンテカルロ統合ルーチンを呼び出すには、この構造体が必要です)

前に述べたように、これは 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

これまでのところ、2 つの解決策が見つかりました。

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 に答える