繁体   English   中英

C ++:任意函数作为函数的参数

[英]C++: Arbitrary function as argument of function

假设我想编写一个通用的数值积分脚本,该脚本采用一个用户定义的函数并对变量int x积分。 进一步假设该函数可以调用任意数量的数据列表。 例如,假设我希望集成器f_integrator能够集成以下任何一个:

integrand(x)=f(x)

integrand(x)=f(x)*g(x)

integrand(x)=(f(x)+g(x)/h(x))

integrand(x)=pow(f(x),2)*k(x)

然后,似乎我们需要它能够调用一个定义良好的函数 ,而无需指定该函数接受多少个参数(也许我们需要指定其中的一部分,例如函数必须具有int x )。 如果是这样,那么我们如何实施呢? 如果我们应该以另一种方式来做,该怎么办?

如果需要传递未知数量的参数,则可以将可变参数模板用于f_integrator

template<typename F, typename... Args >
double f_integrator(F integrand, std::tuple<Args...> const &bounds){
// integrate
} 

为了使它可以用于具有任意参数类型的函数(假设整数的类型为double ,如果需要,还可以为返回类型添加另一个模板参数)。 模板参数F充当函数类型的角色。 然后,您可以直接在函数上调用f_integrator ,例如lambda

 double integral = f_integrate([](double x){return f(x)*g(x);},
                               std::make_tuple(1.0,2.0));

请注意,您可以将任何可调用对象传递给f_integrate ,因为该callable返回了您可以集成的内容。

使用std::tuple允许以某种在函数体中可处理的方式传递积分区域的边界。 当然,如果您考虑非平凡的集成区域,事情会变得更加复杂,但是您仍然可以传递由Args数组表示的网格,以将集成区域上的信息传递给f_integrator

如何进行积分本身是另一回事,但是在一个参数与另一个参数之间进行迭代积分的效率不是很高,如果您要进行高维积分,则蒙特卡洛积分可能是一个好方法。

这是一个非常通用的解决方案,并且给出了一些温和的假设,因此有很多便捷的实现方法(对于可变参数模板而言,编写积分器的主体并不是一件容易的事)。 如果被积数的所有参数都是相同的类型,我们可以像普通的向量一样传递边界

template<typename F, typename T>
double f_integrate(F integrand, std::vector<T> const &bounds){
  // integrate, much more convenient
}

现在,您提供的示例仅需要一个参数,因此,如果您可以集成一维函数,可以稍微简化一下。 如果仅通过一个参数传递函数,则不需要可变参数模板,只需使用

template<typename F, typename T=double>
double f_integrate(F integrand, T const& lower_bound, T const& upper_bound){
   // integrate
}

可能甚至不需要第二个参数,因为您可能只对实数进行积分(请注意,对整数的积分只是离散的和,因此在这种情况下无需进行数字积分)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM