ar2015
ar2015

Reputation: 6150

pass an object and one of its methods as an argument

I have a model with a few algorithms and I have to test the algorithms so many times in different ways. It is very hard for me to change anything in the class just for the purpose of testing (in so many files). I want to tell the compiler to run which method on which object. Each time, I have two algorithms to compare and I have over 10 test filers test1.cpp ... test10.cpp ... . Therefore it is hard to adjust each test files. The name of algorithms is also different in each file. I am looking for a way to pass the methods to the profiler from the main. In fact adjusting everything only from the main. I only copy/past the algorithms into the model class and then fix the main function without changing the anything inside the class (after copy/pasting the algorithms) or the profile function. The following code shows what I need. Feel free to tweak the structure of this code without breaking the model class into two classes. I must remain only one class.

Please do not send (migrate) this question to code review since it is a draft code (last time I got so many down votes just because of mistake of someone.)

Welcome to the simplest and most readable suggestion.

#include <iostream>

class CModel
{
public:
    // ....
    // ....
    // ....

    CModel()
    {
    }

    double algorithm1()
    {
        double result=0;
        // ...
        return result;
    }


    double algorithm2()
    {
        double result=0;
        // ...
        return result;
    }

};

void profiler(CModel &model,double (*algorithm)(void))
{
    // CTimer mytimer;
    // mytimer.start();
    // using model fields here
    double result=model.(*algorithm)();
    // mytimer.stop();
    std::cout<<"out: "<<result<<std::endl;
    // std::cout<<"time elapsed: "<<mytimer.duration;
}

int main()
{
    CModel m1, m2;
    // m1.something= something else;
    // m2.something= something else;
    profiler(m1,m1.algorithm1); // *** impossible ***
    profiler(m2,m2.algorithm2); // *** impossible ***
    return 0;
}

Upvotes: 1

Views: 63

Answers (2)

douyw
douyw

Reputation: 4074

How about changing profiler function in this way?

#include <functional>

void profiler(std::function<void()> func) {
    // CTimer mytimer;
    // mytimer.start();
    func();
    // mytimer.stop();
    // std::cout<<"time elapsed: "<<mytimer.duration;   
}

Use profiler:

CModel m1, m2;
profiler([&m1](){
   double d = m1.algorithm1();
});
profiler([&m2](){
   double d = m2.algorithm2();
});

Or just the same object if possible:

CModel m1;
profiler([&m1](){
   double d = m1.algorithm1();
});
profiler([&m1](){
   double d = m1.algorithm2();
});

Upvotes: 0

James Adkison
James Adkison

Reputation: 9602

  1. You need to declare the function to take a member function

    void profiler(CModel &model, double (CModel::*algorithm)())
    
  2. You need to pass the function a pointer to the member function

    profiler(m1, &CModel::algorithm1);
    profiler(m2, &CModel::algorithm2);
    
  3. You need to call the member function correctly

    double result = (model.*algorithm)();
    

See C++, function pointer to member function for more details.

Upvotes: 3

Related Questions