I am trying to write a function that accepts any other arbitrary function as an input and times it, then returns the results of that function. I have been at it for a couple hours now and think I'm getting pretty close, but I still can't quite figure out how to get it to compile.
This is what I have so far:
// Some arbitrary function to pass to the timer
int DoSomething(int x, double y)
{
// Does something with x and y
return 0;
}
// Function used to time another function and return its result
template <typename T, typename Function, typename... Args>
T GetRuntime(const std::string& name, const Function& function, Args&&... args)
{
std::cout << name << " started..." << std::endl;
auto start = std::chrono::high_resolution_clock::now();
T result = function(std::forward<Args>(args)...);
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
std::cout << name << " complete - duration: " << duration.count() << " milliseconds." << std::endl;
return result;
}
int main()
{
// Doesn't compile
int output = GetRuntime("DoSomething", DoSomething, 42, 42.42);
}
Am I approaching this the right way? If so, what do I need to change to make this work? If not, what is a better way to approach this problem?
The problem here is that T
is not deducable in your function. The value you are assigning the return to does not participate in template parameter deduction. To use it as is, you need to specify the return type by using
int output = GetRuntime<int>("DoSomething", DoSomething, 42, 42.42);
^^^ specify T is an int
but we can make this better by using auto
for the return type of the function. Using that turns the function into
template <typename Function, typename... Args>
auto GetRuntime(const std::string& name, const Function& function, Args&&... args)
{
std::cout << name << " started..." << std::endl;
auto start = std::chrono::high_resolution_clock::now();
auto result = function(std::forward<Args>(args)...);
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
std::cout << name << " complete - duration: " << duration.count() << " milliseconds." << std::endl;
return result;
}