[英]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.