c++ - C++:任意函数作为函数的参数
问题描述
假设我想编写一个通用的数值积分脚本,它采用用户定义的函数并对变量进行积分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)
然后似乎我们需要它能够只调用一个定义明确的 function,而无需指定该函数需要多少个参数(也许我们需要指定其中的一部分,例如函数必须有一个int x
)。如果是这样,那我们该如何实施呢?如果我们应该以另一种方式来做,怎么做?
解决方案
f_integrator
如果需要传递未知数量的参数,可以使用可变参数模板
template<typename F, typename... Args >
double f_integrator(F integrand, std::tuple<Args...> const &bounds){
// integrate
}
允许它处理采用任意参数类型的函数(假设积分是double
type ,如果需要,还可以为返回类型添加另一个模板参数)。模板参数F
扮演函数类型的角色。然后,您可以f_integrator
直接调用函数,例如 lambda
double integral = f_integrate([](double x){return f(x)*g(x);},
std::make_tuple(1.0,2.0));
请注意,您可以将任何可调用对象传递给f_integrate
,因为可调用对象返回您可以集成的内容。
Usingstd::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
}
可能,甚至不需要第二个参数,因为您可能只对实数进行积分(请注意,整数上的积分只是离散和,因此在这种情况下不需要以数字方式执行积分)。
推荐阅读
- python - Python 没有正确找到列表中的值
- node.js - 如何从“pcap TCPTracker”中检索“http 标头和正文”
- android - 使用 ArrayList 在活动之间发送 Json 数据
- c# - 是否有必要在 using 块内使用 using 块?
- python - Tkinter 绑定事件传递给函数而不是变量
- java - Android - 在编译时查找重复的字符串
- algorithm - 不同输入大小的时间复杂度
- ruby-on-rails - 嵌套条件不返回任何结果
- javascript - 在Typescript中子类化Fabric JS类型反序列化时导致错误
- javascript - 未捕获的 ReferenceError:弹出窗口在 javascript 中不起作用