2012-05-03 2 views
2

私は特定の場合に関数ポインタを使いたいと思います。私は、次のプロトタイプを持つ関数fooを使用していますいくつかの固定値で引数としてC++関数ポインタを渡す方法はありますか?

foo(double (*func)(double,double)); 

私は、通常の方法fooを呼び出すことができます。

double bar(double x, double y) { 
    //stuff 
}; 

int main(void) { 
    foo(bar); 
    return 0; 
}; 

が、私はと同等の機能を得るためにxの値を凍結したいと思いますこのようなdouble (*func)(double)

foo(bar(x,double)) 

これに似た構文がC++に存在していますか?

+3

'std :: bind'をチェックしてください。関数内の1つ以上の引数に値をバインドすることができます。 – chris

+0

ありがとう、私はこれをチェックします。 – vanna

+1

あなたは 'のstd :: function'、その後、あなたはブースト同等物を使用することができます' 'で見つかったプレースホルダとの'のstd :: bind'のためのC++ 11のサポートを持っていない場合。 – AJG85

答えて

1

あなたがC++ 11を持っている場合は、std::bindを使用することができます。 1つの迅速な動きで各要素に5を追加することにより、ベクトルを変換し、この例を考えてみましょう:あなたの例については

#include <iostream> 
using std::cout; 

#include <functional> 
using std::plus; 
using std::bind; 
using std::placeholders::_1; 

#include <vector> 
using std::vector; 

#include <algorithm> 
using std::transform; 

int main() 
{ 
    vector<int> v {1, 3, 6}; 

    //here we bind the value 5 to the first argument of std::plus<int>() 
    transform (v.begin(), v.end(), v.begin(), bind (plus<int>(), _1, 5)); 

    for (int i : v) 
     cout << i << ' '; //outputs "6 8 11" 
} 

、私はこのようなそれに近い何かを書くことができました:

#include <iostream> 
using std::cout; 

#include <functional> 
using std::bind; 
using std::function; 
using std::placeholders::_1; 

void foo (function<double (double, double)> func) //take function object 
{ 
    //try to multiply by 3, but will do 2 instead 
    for (double i = 1.1; i < 5.6; i += 1.1) 
     cout << func (i, 3) << ' '; 
} 

double bar (double x, double y) 
{ 
    return x * y; 
} 

int main() 
{ 
    foo (bind (bar, _1, 2)); 
} 

出力:

2.2 4.4 6.6 8.8 11 

でも、私は何かをovercomplicatedている場合があります。実際にはstd::bindstd::functionの両方を使用していました。あなたがしたいがstd::bind/std::functionを使用していない場合は

2

は、ここでは、2つの選択肢です。あなたのコンパイラを想定し

あなたがxをバインドするためにラムダを使用することができ、関数ポインタにステートレスラムダの変換をサポートします。

void foo(double (*f)(double, double)) { (*f)(3.14159, 2.71828); } 

double bar(double x, double y) { return x * y; }; 

int main() 
{ 
    foo([](double x, double y) -> double { return bar(1.0, y); }); 
    return 0; 
} 

それともあなたも任意の関数オブジェクトを受け入れ、テンプレートにfooを変更することができます。そうすれば、キャプチャしたラムダを使うことができます:

template<typename TFunc> 
void foo(TFunc f) { f(3.14159, 2.71828); } 

double bar(double x, double y) { return x * y; }; 

int main() 
{ 
    double fixedprm = 1.0; 
    foo([fixedprm](double x, double y) -> double { return bar(fixedprm, y); }); 
    return 0; 
} 
関連する問題