是否可以通过将一个参数设置为固定值来从n参数函数中获取(n-1) - 参数函数?

时间:2011-10-21 10:28:21

标签: c++ partial-application

我想知道在C ++中是否可以通过将第n个参数的值设置为某个值(在运行时确定)来获取带有n个参数的函数中的(n-1)个参数的函数? / p>

E.g。我想做类似以下的事情:

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 (float a, float b)(在此处将“foo_c”读作“foo下标c”),我想要将foo_c分别作为参数传递给bar

这在C ++中是否可行? 据我所知,使用上面的函数指针是不可能的。有没有其他办法做这样的事情?

我简单地考虑过将foo作为一个函数模板,但这不会起作用,因为我想在运行时设置它的第三个参数。

显而易见的解决方案当然是修改bar以便将类型float f(float q, float r, float t)作为其第三个参数,但这会使代码重复性降低(并且看起来不那么优雅)。我也希望将其他函数传递给bar,其中一些函数只接受两个参数,三个以上或不同类型的参数,在将它们传递给{之前,我需要将它设置为固定值。 {1}}。

在这种情况下,我无法确定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)之类的方式调用它}。沿着这些方向的任何事情都可以发挥作用吗?

2 个答案:

答案 0 :(得分:4)

您无法使用函数指针执行此操作,但是,可以使用函数对象完成此操作。如果您使用的是C ++ 03,我建议您查看Boost.Bind。如果您使用的是C ++ 11,std::bind是标准的一部分,并以相同的方式工作。 C ++ 11还引入了内置的lambda,它可以完成您正在尝试的内容。

要存储bind或lambda的结果,可以在C ++ 03中使用Boost.Function或在C ++ 11中使用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中,您可以使用bind和function的标准化版本,或者您可以使用lambda功能:

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);
}

答案 1 :(得分:4)

你不能用这样的函数指针来做,但你可以用类似函数的对象来做。 C ++ 11为您提供std::bindstd::function(以及lambdas,但我不太了解它们给出一个例子);在C ++ 03中,boost::bindboost::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));
}