更好地设计使用具有不同参数的函数指针

zen*_*nna 2 c++ function-pointers

我有一个优化算法,可以找到图形的最佳分区.

分区的质量有很多度量(被优化的变量),所以我认为使用函数指针来处理这些质量函数是个好主意,并将其传递给我的优化算法函数.

这工作正常,但问题是不同的质量函数采取一些不同的论点.

例如,一个质量函数是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)
Run Code Online (Sandbox Code Playgroud)

并用于优化功能:

cliques::find_optimal_partition_louvain(my_new_graph, markov_times, &cliques::find_linearised_stability);
Run Code Online (Sandbox Code Playgroud)

但是另一个质量函数find_modularity不需要markov_time参数.当然,我可以把它作为一个参数包括在内,而不是在函数中使用它,但这似乎是不好的做法,并且一旦我开始添加许多不同的质量函数就会变得笨拙.

对于这种情况,什么是更好的设计?

Ben*_*ley 6

使用函数对象.其中一个函数对象可以有一个传递给构造函数的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
    }
};
Run Code Online (Sandbox Code Playgroud)

(您可能需要调整常数/参考值以满足您的需要)

然后你可以像这样调用你的函数:

cliques::find_optimal_partition_louvain(my_new_graph, cliques::find_linearised_stability(markov_times));
Run Code Online (Sandbox Code Playgroud)

"在声明...函数时我会使用什么类型的函数对象?"

使它成为一个函数模板,将函数对象类型作为模板参数,因此:

template<typename PR>
whatever find_optimal_partition_louvain(my_new_graph, PR & pr)
{
    ...
    pr(my_new_graph, partition, stabilities);
    ...
}
Run Code Online (Sandbox Code Playgroud)