I happen to compute the elapsed running time of various functions and algorithms in my research project, so, I decided to define an elapsed_time
function which might take various type of functions with various number of arguments(if any) and also various return types or none (void
).
I want to pass a function to this elapsed_time
function and make use of a function pointer, pointing to the function that has been passed as an argument of the elapsed_time
function, and thus compute its elapsed running time.
I am not sure if my code is even close to be correct, but I did my best as a newbie in programming, as follows:
MWE:
#include <iostream>
#include <chrono>
template<class return_type, class ... argument_types>
void elapsed_time(return_type func(argument_types ... args)){
return_type (* func_ptr)(argument_types ... args) = & func;
std::chrono::time_point<std::chrono::high_resolution_clock> start_;
std::chrono::time_point<std::chrono::high_resolution_clock> end_;
start_ = std::chrono::high_resolution_clock::now();
/* Put the Function whose elapsed time matter right HERE */
func_ptr(); /// What to pass here?
/* Put the Function whose elapsed time matter right HERE */
end_ = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_time (end_ - start_);
const double seconds(elapsed_time.count());
cout << "\nRuntime: " << seconds << " s\n\n";
}
and now lest consider I have a function to be passed to elapsed_time function, as follows:
vector<Point_CCS_xy> fun(const vector<Point_CCS_xy> point_vec, const Point_CCS_xy inquiry_pnt, const int sz);
where Point_CCS_xy
is a class of cartesian coordinates (x,y), i.e.,
struct Point_CCS_xy {
long double x_coordinate;
long double y_coordinate;
};
My questions:
- Is the function I have written correct? what should I pass to func_ptr() as commented in the body of the
elapsed_time
function? Passingargument_types ... args
leads to the error:'argument_types' does not refer to a value
- In the main(), how to pass
vector<Point_CCS_xy> fun(const vector<Point_CCS_xy> point_vec, const Point_CCS_xy inquiry_pnt, const int sz);
function to theelapsed_time
function?
In advance, I appreciate that you share your thoughts and comments.
CodePudding user response:
I recommend the following approach
template<typename Func, typename... Args>
void elapsed_time(Func f, Args&&... args)
{
std::chrono::time_point<std::chrono::high_resolution_clock> start_;
std::chrono::time_point<std::chrono::high_resolution_clock> end_;
start_ = std::chrono::high_resolution_clock::now();
std::invoke(f, std::forward<Args>(args)...);
end_ = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_time (end_ - start_);
const double seconds(elapsed_time.count());
cout << "\nRuntime: " << seconds << " s\n\n";
}
In the above I make the entire function type a single template parameter. This has the advantage of allowing you to pass any type of callable object, not just function pointers. I then use std::invoke
to actually call the passed in object as it is design to handle invoke any callable with the provided arguments.
So for your fun
function, you would pass it to this version of the elapsed_time
like
elapsed_time(fun, point_vec, inquiry_pnt, sz);
If the callable you are passing happens to be an overloaded function, then you would just need to wrap that call in a lambda expression like
elapsed_time([&](){ fun(point_vec, inquiry_pnt, sz); });