C ++: Оболочка функции, которая ведет себя так же, как сама функция - PullRequest
15 голосов
/ 18 мая 2009

Как я могу написать упаковщик, который может обернуть любую функцию и может быть вызван так же, как сама функция?

Причина, по которой мне это нужно: мне нужен объект Timer, который может обернуть функцию и вести себя так же, как сама функция, плюс он регистрирует накопленное время всех своих вызовов.

Сценарий будет выглядеть так:

// a function whose runtime should be logged
double foo(int x) {
  // do something that takes some time ...
}

Timer timed_foo(&foo); // timed_foo is a wrapping fct obj
double a = timed_foo(3);
double b = timed_foo(2);
double c = timed_foo(5);
std::cout << "Elapsed: " << timed_foo.GetElapsedTime();

Как я могу написать этот Timer класс?

Я пытаюсь что-то вроде этого:

#include <tr1/functional>
using std::tr1::function;

template<class Function>
class Timer {

public:

  Timer(Function& fct)
  : fct_(fct) {}

  ??? operator()(???){
    // call the fct_,   
    // measure runtime and add to elapsed_time_
  }

  long GetElapsedTime() { return elapsed_time_; }

private:
  Function& fct_;
  long elapsed_time_;
};

int main(int argc, char** argv){
    typedef function<double(int)> MyFct;
    MyFct fct = &foo;
    Timer<MyFct> timed_foo(fct);
    double a = timed_foo(3);
    double b = timed_foo(2);
    double c = timed_foo(5);
    std::cout << "Elapsed: " << timed_foo.GetElapsedTime();
}

(Кстати, мне известны gprof и другие инструменты для профилирования времени выполнения, но наличие такого объекта Timer для регистрации времени выполнения нескольких выбранных функций более удобно для моих целей.)

Ответы [ 11 ]

0 голосов
/ 18 мая 2009

В C ++ функции являются гражданами первого класса, вы можете буквально передать функцию как значение.

Так как вы хотите взять int и вернуть double:

Timer(double (*pt2Function)(int input)) {...
...