簡體   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