Supposing I have a function (a decorator) that measures the duration of given function:
#include <unistd.h>
void measure(void (*f)()) {
time_t tBegin = time(NULL);
f();
time_t tEnd = time(NULL);
cout << "Duration: " << (tEnd - tBegin) << " sec" << endl;
}
And I want to measure the duration of a method of a class. For example:
class Myclass {
private:
double _d;
public:
Myclass(double d) : _d(d) {}
void run() {
measure(m);
}
void m() const {
usleep(1000000 * _d);
}
};
int main() {
Myclass obj(2.0);
obj.run();
return 0;
}
Such implementation leads to the error:
error: invalid use of non-static member function
Is there a way in C++ to implement it correctly? It's supposed not to modify the external function measure
and the measured method is exactly non-static (it uses data of the instance). The measurement should be inside of the method run
.
I need solution for C++ 1998/2003 Standard.
Change measure
to a function template to allow you to use any callable, not just a function.
Use a lambda function in run
.
#include <iostream>
#include <time.h>
#include <unistd.h>
template <typename F>
void measure(F f) {
time_t tBegin = time(NULL);
f();
time_t tEnd = time(NULL);
std::cout << "Duration: " << (tEnd - tBegin) << " sec" << std::endl;
}
class Myclass {
private:
double _d;
public:
Myclass(double d) : _d(d) {}
void run() {
measure([=](){m();});
}
void m() const {
usleep(1000000 * _d);
}
};
int main() {
Myclass obj(2.0);
obj.run();
return 0;
}
Since, you are not allowed to modify measure
, you can use a helper class template and a function template to make it possible for you to use any callable.
#include <iostream>
#include <time.h>
#include <unistd.h>
void measure(void (*f)()) {
time_t tBegin = time(NULL);
f();
time_t tEnd = time(NULL);
std::cout << "Duration: " << (tEnd - tBegin) << " sec" << std::endl;
}
template <typename F>
struct MeasureFunctor
{
static F* f_;
static void run(){(*f_)();}
};
template <typename F> F* MeasureFunctor<F>::f_ = nullptr;
template <typename F>
void measure(F f) {
MeasureFunctor<F>::f_ = &f;
measure(MeasureFunctor<F>::run);
}
class Myclass {
private:
double _d;
public:
Myclass(double d) : _d(d) {}
void run() {
measure([=](){m();});
}
void m() const {
usleep(1000000 * _d);
}
};
int main() {
Myclass obj(2.0);
obj.run();
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With