1

C++ では、n 番目の引数の値を何らかの値 (実行時に決定される) に設定することで、n 引数を取る関数から (n-1) 個の引数を取る関数を取得できるかどうか疑問に思っていました。

たとえば、次のようなことをしたいと思います。

float foo(float a, float b, float c){
  // do some stuff
}

float bar(float x, float y, float f(float q, float r)){
  return f(x,y);
}

int main(){
  double (*function)(float, float);
  float some_value;
  // somehow determine some_value, e.g. read from stdin.
  // Now I would like to set function something along the lines of:
  function = foo( . , . , some_value)
  return bar(123, 456, function);
}

概念的にfooは、 は によってインデックス付けされた関数cのファミリ、つまり関数のファミリ(ここでは「foo_c」を「foo subscript c」と読みます) であり、それぞれへのポインタを引数としてfoo_c (float a, float b)に渡したいと考えています。foo_cbar

これはC++でまったく可能ですか? 私の知る限り、これは上記の関数ポインターでは不可能です。このようなことを行う他の方法はありますか?

関数テンプレートを作成することを簡単に検討しfooましたが、実行時に3番目の引数を設定したいので、これは機能しません。

明白な解決策はもちろん、3 番目の引数としてbartype を受け取るように修正することですが、これではコードの再利用性が大幅に低下します (そして洗練されていないように見えます)。float f(float q, float r, float t)他の関数も同様に渡したいと思いbarます。その中には、引数を 2 つ、3 つ以上、または異なる型の引数しかとらないものもあり、それらを に渡す前に何らかの方法で固定値に設定する必要がありますbar

barこの場合、 の行に沿ってテンプレート関数を作成し、 のtemplate <typename T, typename S> float bar(float x, float y, T f(float a, float b, S param), S parameters)ようなものを使用して呼び出すことができるかどうかを完全に理解することはできませんでしたbar <double *(float, float, float), float> (123, 456, function, parameters)。これらの線に沿ったものはまったく機能しますか?

4

2 に答える 2

4

関数ポインタではできませんが、関数オブジェクトでは実行できます。C++03 を使用している場合は、 Boost.Bindを確認することをお勧めします。C++11 を使用している場合std::bindは、標準の一部であり、同じように機能します。C++ 11 は、あなたが試みていることを行う組み込みのラムダも導入しています。

バインドまたはラムダの結果を格納するには、C++03 またはC++11 でBoost.Functionを使用できます。std::function

この例は、C++03 で行う方法です。

float foo(float a, float b, float c){
  // do some stuff
}

float bar(float x, float y, boost::function<float(float,float)> f){
   return f(x,y);
}

int main(){
  boost::function<float(float,float)> func;
  float some_value;
  // somehow determine some_value, e.g. read from stdin.
  // Now I would like to set function something along the lines of:
  func= boost::bind(foo, _1, _2, some_value);
  return bar(123, 456, func);
}

C++11 では、バインドと関数の標準化されたバージョンを使用するか、ラムダ機能を使用できます。

float foo(float a, float b, float c){
  // do some stuff
}

float bar(float x, float y, std::function<float(float,float)> f){
   return f(x,y);
}

int main(){
  std::function<float(float,float)> func;
  float some_value;
  // somehow determine some_value, e.g. read from stdin.
  // Now I would like to set function something along the lines of:
  func= [some_value](float x, float y) { return foo(x,y,some_value); };
  return bar(123, 456, func);
}
于 2011-10-21T10:36:21.317 に答える
4

そのような関数ポインタではできませんが、関数のようなオブジェクトではできます。C++ 11 ではstd::bindand std::function(ラムダもありますが、例を挙げられるほどよく知りません); C++03 でboost::bindありboost::function、非常によく似ています。

float foo(float a, float b, float c){
  // do some stuff
}

float bar(float x, float y, function<float(float, float)> f){
  return f(x,y);
}

int main(){
  float some_value;
  // somehow determine some_value, e.g. read from stdin.

  return bar(123, 456, bind(foo,_1,_2,some_value));
}
于 2011-10-21T10:36:36.383 に答える