2017-05-16 7 views
0

C++で関数やその他の関数にパラメータを固定して渡す方法があるかどうかを知りたいと思います。yを固定したパラメータとして関数f(x、y)を渡します。

ここexemple説明するために:

#include<math.h> 
#include<iostream> 

double myfunc(double x) { return 5*x; } 

double gaussian(double x , double s , double v) { return exp((x-v)*(x-v)/(s*s)) ; } 

double Trapeze1D(const double x_min, const double x_max, double (*fonction)(double)) 
{ 
    double nb_pts = 100.0 ; 
    double integrale = 0.0 ; 
    double dx = (x_max - x_min)/(double) nb_pts ; 

    double x_k ; 

    while (k < nb_pts-1) 
    { 
     k++; 
     x_k = x_min + (double) k * dx ; 
     integrale += fonction(x_k) ; 
    }  

    integrale *= dx ; 
    return integrale ; 
} 

int main() 
{ 
    cout << Trapeze1D(0.0,1.0,myfunc) << endl ; // <-- works fine 
    cout << Trapeze1D(0.0,1.0, gaussian(double , 2,3)) << endl ; // <-- I would like something like that ... 

    // Also tried : 
    double tmp(double x) = gaussian(x, 2,3) ; // <-- does not work C++ does not allow definition of function inside function ... 
    cout << Trapeze1D(0.0,1.0, tmp) << endl ; 
} 

を私の問題は以下の通りです、私は(積分法は、最終的にははるかに洗練されただろう)の機能のいくつかの異なるタイプを統合し、それらの多くする必要があります

class gaussian 
{ 
    public: 
    double eval(double x) ; 
    void get(double s, double v) ; 
    private: 
    double s ; 
    double v ; 
} 

double gaussian::eval(double x){ return exp((x-v)*(x-v)/(s*s)) ; } 

int main() 
{ 
    gaussian G; 
    G.get(1.0,2.0) ; 
    cout << Trapeze1D(0.0,1.0,G.eval) << endl ; // <-- error 
} 

が、私は目を取得する:私も、このようなクラスを使用してみましたがガウス、多項式、ベータ法律...

などのパラメータに依存します次のエラー:非静的メンバー関数への参照を呼び出す必要があります

ご協力いただければ幸いです。 多くのありがとう

+3

は、サウンドと'std :: bind'。 – NathanOliver

+0

@NathanOliver彼はいません – Sopel

答えて

1

これを行う方法はいくつかあります。

int main() 
{ 
    std::cout << Trapeze1D(0.0, 1.0, myfunc) << std::endl; 

    auto tmp = [](double x){ return gaussian(x, 2, 3); }; 
    std::cout << Trapeze1D(0.0, 1.0, tmp) << std::endl; 
} 

これはあなたのガウス関数をラップし、一時的なラムダ関数を作成します。最も簡単なのは、あなたが実際に非常に接近していたものです。あなたは、これはより柔軟になりたかった、とあなたはややsvを変更するに興味を持っていた場合は

double myfunc(double x) { return 5*x; } 

double gaussian(double x , double s , double v) { return exp((x-v)*(x-v)/(s*s)) ; } 

double tmp(double x) { return gaussian(2, 3, x); } 

:あなたはラムダに慣れていない場合、これはファイルの先頭にTMPを宣言するの一時的なバージョンです。定期的に、あなたは常に数子のクラスを作ることができるが、それは関数ポインタやファンクタに取るのいずれかにごTrapeze1D機能を変更する作業のビットを伴うだろう:あなたは `のstd :: function`を必要とするよう

template <typename FuncType> 
double Trapeze1D(const double x_min, const double x_max, FuncType fonction) 
{ 
    ... 
    integrale += fonction(x_k); 
    ... 
} 

class gaussian_functor 
{ 
public: 
    gaussian_functor(double s, double v) 
     : m_s(s) 
     , m_v(v) 
    {} 

    double operator() (double x) const { return exp((x - m_v)*(x - m_v)/(m_s*m_s)); } 
private: 
    double m_s; 
    double m_v; 
}; 


int main() 
{ 
    std::cout << Trapeze1D(0.0, 1.0, myfunc) << std::endl; 

    gaussian_functor my_functor(2.0, 3.0); 
    std::cout << Trapeze1D(0.0, 1.0, my_functor) << std::endl; 
} 
+0

Trapeze1D関数の定義をdouble(* fonction)(double)からFuncType関数に変更する必要がある理由を説明できますか? – Bastien

+0

あなたはテンプレートに精通していますか?上記のようにテンプレート化されるように定義を変更すると、オブジェクトに 'double'を渡して呼び出され、' double'を返す関数があれば、オブジェクトを 'fonction'として取り込むことができます。テンプレート化された定義では、以前と同じように関数ポインタを渡すことができます。また、関数を渡すこともできます。 – dwcanillas

+0

大変感謝して、私の問題を解決しました! – Bastien

関連する問題