I am trying to write a template that will take any function and log its time and after some struggle with template syntax i have come up with below solution:
template <typename Func, typename... Args>
auto timeMyFunction(Func f, Args... args)-> typename
std::enable_if<std::is_same<decltype(f(args...)),void>::value,void>::type
{
auto start = std::chrono::steady_clock::now();
f(args...);
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end-start;
std::cout << "Time to complete function " << diff.count()<<std::endl;
}
template <typename Func, typename... Args>
auto timeMyFunction(Func f, Args... args)-> typename std::enable_if<!std::is_same<decltype(f(args...)),void>::value,decltype(f(args...))>::type
{
auto start = std::chrono::steady_clock::now();
auto ret = f(args...);
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end-start;
std::cout << "Time to complete function " << diff.count()<<std::endl;
return ret;
}
But what i feel is this solution is some kind of Jugaad (https://en.wikipedia.org/wiki/Jugaad) and need your help in finding better solution. So what i am looking for is template that will calculate processing time of passed function and if possible can it be done without overloading as in above code i need to overload because i can't declare something like void ret
. Also is my usage of decltype
correct here.
Please suggest how it can be modified so that i can time class member and static function also via this template.
Not a great solution but... you can create a template
exec
struct with a method that return the value off(args...)
, if the return type isn'tvoid
, or a fake value (anint
, by example), otherwise.By example
So you can detect the return type (
RetType
, in the following example), save the value (fake value, in the void case) returned byexecStruct::exec(f, args...)
and return the saved value casting it toretType
. So, ifRetType
isvoid
, casting the fake value tovoid
is like writingreturn;
.The following is a full working example
Wrap the time computation/display in a class:
And then