2

Could some one help me how to implement this code?

I need to pass a function to another function:

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

This function gets the function as a template type and calls it on an object

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

Note that method1 is a function template as well:

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

What is the legal syntax for it?

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;
}
zahmati
  • 1,261
  • 1
  • 10
  • 18

3 Answers3

2

The key is that method1 is a function template:

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

As such, it's not a function... it's a family of functions. process_time expects a single function, so you just have to pass it the one function that you want to use:

std::cout << process_time(method1<int>) << std::endl;
Barry
  • 286,269
  • 29
  • 621
  • 977
1

This is the closest to your code that compiles:

#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;
}
Arkanosis
  • 2,229
  • 1
  • 12
  • 18
1

Change your process time line with time += to:

   time += algorithm(&model,arg1);

then call it with:

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

or in C++14:

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

which leaves the choice of what kind of vector it will pass to method1 up to process_time instead of fixing it at the calling site.

Basically, this avoids dealing with pointer-to-member variables. Instead, the algorithm in process_time is just a map from Model x vector to double. This also means that we can have a non-member algorithm.

If you don't like the verbosity of the above at the call site, you can keep the changes to process_time and change the call to:

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

as std::ref takes a pointer to a member function, and returns a callable object that takes a pointer-to-Model as the first argument, and std::vector<int>& as the second. Which matches how we use it.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524