[英]Better design for using function pointers with varying arguments
我有一個優化算法,可以找到圖形的最佳分區。
分區的質量有很多度量(被優化的變量),所以我認為使用函數指針來處理這些質量函數是個好主意,並將其傳遞給我的優化算法函數。
這工作正常,但問題是不同的質量函數采取一些不同的論點。
例如,一個質量函數是find_linearised_stability
,它需要markov_time
參數:
float find_linearised_stability(cliques::Graph<T> &my_graph, cliques::Partition &my_partition,
std::vector<float> &markov_times, std::vector<float> &stabilities)
並用於優化功能:
cliques::find_optimal_partition_louvain(my_new_graph, markov_times, &cliques::find_linearised_stability);
但另一個質量函數find_modularity
不需要markov_time參數。 當然,我可以把它作為一個參數包括在內,而不是在函數中使用它,但這似乎是不好的做法,一旦我開始添加許多不同的質量函數,就會變得笨拙。
對於這種情況,什么是更好的設計?
使用函數對象。 其中一個函數對象可以有一個傳遞給構造函數的markov_time成員:
struct find_linearised_stability {
std::vector<float> & markov_times_;
find_linearised_stability(std::vector<float> & markov_times)
:markov_times_(markov_times)
{}
float operator () (cliques::Graph<T> &my_graph, cliques::Partition &my_partition,
std::vector<float> &stabilities)
{
// use markov_times_ in here, we didn't need to pass it since it's a member
}
};
(您可能需要調整常數/參考值以滿足您的需要)
然后你可以像這樣調用你的函數:
cliques::find_optimal_partition_louvain(my_new_graph, cliques::find_linearised_stability(markov_times));
“在聲明...函數時我會使用什么類型的函數對象?”
使它成為一個函數模板,將函數對象類型作為模板參數,因此:
template<typename PR>
whatever find_optimal_partition_louvain(my_new_graph, PR & pr)
{
...
pr(my_new_graph, partition, stabilities);
...
}
你唯一的選擇是boost :: bind或類似存儲在boost :: function或類似的東西。
如果分析顯示速度太慢,那么你將會陷入“糟糕的練習”版本,因為任何替代方案都會與UB發生沖突和/或最終變得像更合理的替代方案一樣“緩慢”。
示例源代碼:
#include <iostream>
#include <cstddef>
#include <algorithm>
#include <boost/bind.hpp>
using namespace std;
void output(int a, int b)
{
cout << a << ", " << b << '\n';
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
for_each(arr, arr + 5, bind(output, 5, _1));
return 0;
}
輸出:
5, 1 5, 2 5, 3 5, 4 5, 5
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.