将模板方法作为参数传递

Pass a template method as an argument

谁能帮我实现这段代码?

我需要将一个函数传递给另一个函数:

std::cout << process_time(Model::method1) << std::endl;

此函数获取函数作为模板类型并在对象上调用它

template <typename F>
double process_time(F algorithm)
{
    Model model;
    double time=0;
    do
    {
        // ...
        time += model.algorithm(arg1);
    } while (! stop_criteria);
    return time;
}

注意method1也是一个函数模板:

template <typename T>
double method1(std::vector<T> &v)
{
    ...
}

它的合法语法是什么?

main.cpp

#include <iostream>
#include <vector>

class Model
{
public:

    template <typename T>
    double method1(std::vector<T> &v)
    {
        double t = 0;
        //...
        return t;
    }

    template <typename T>
    double method2(std::vector<T> &v)
    {
        double t = 0;
        //...
        return t;
    }

};

template <typename F>
double process_time(F algorithm)
{
    Model model;
    double time = 0;
    bool stop_criteria = false;
    do
    { 
        std::vector<int> arg1;
        // ...
        time += model.algorithm(arg1);
    } while (!stop_criteria);
    return time;
}

int main()
{
    std::cout << process_time(Model::method1) << std::endl;
    return 0;
}

关键是method1是函数template:

template <typename T> double method1(std::vector<T>& );

因此,它不是 a 函数...它是一个函数族。 process_time 需要一个函数,因此您只需将要使用的 one 函数传递给它:

std::cout << process_time(method1<int>) << std::endl;

这是最接近你编译的代码:

#include <iostream>
#include <vector>

struct Model {
  template <typename T>
  double method1(std::vector<T> &v) {
    double t = 0;
    //...
    return t;
  }
};

template <typename F>
double process_time(F algorithm) {
    Model model;
    double time = 0;
    bool stop_criteria = false;
    do
    { 
        std::vector<int> arg1;
        // ...
        time += (model.*algorithm)(arg1);
    } while (!stop_criteria);
    return time;
}

int main() {
  std::cout << process_time(&Model::method1<int>) << std::endl;
}

process timetime += 更改为:

   time += algorithm(&model,arg1);

然后调用它:

std::cout << process_time([](Model* m, std::vector<int>& v){return m->method1(v);}) << std::endl;

或者在 C++14 中:

std::cout << process_time([](Model* m, auto& v){return m->method1(v);}) << std::endl;

它可以选择将哪种向量传递给 method1 直到 process_time,而不是将其固定在调用站点。

基本上,这避免了处理指向成员变量的指针。相反,process_time 中的 algorithm 只是从 Model x vectordouble 的映射。这也意味着我们可以有一个非会员 algorithm.

如果你不喜欢上面调用站点的冗长,你可以保留对process_time的更改并将调用更改为:

std::cout << process_time(std::ref(&Model::method1<int>)) << std::endl;

as std::ref 接受指向成员函数的指针,returns 接受指向 Model 的指针作为第一个参数的可调用对象,并且 std::vector<int>& 作为第二个。这符合我们的使用方式。