soltzu soltzu - 1 year ago 62
C++ Question

Create variadic template function to measure and execute other function

I am currently trying to implement a function that will take as input any other function and a valid set of input values for that function and return the result of the function as well as printing how long it took to execute it.

Here is what I have until now:

template<typename T, typename... Tail>

T measureAndExecute(const function<T(Tail...)> f, Tail... tail) {
high_resolution_clock::time_point time1 = high_resolution_clock::now();
T res = f(tail...);
high_resolution_clock::time_point time2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(time2 - time1).count();
cout << duration << " milliseconds" << endl;
return res;

And I try to run it with something like this:

int res = measureAndExecute(function<int(vector<int>&, vector<bool>&, unsigned long)> fibonacci, terms, calculated, n-1);

Which is a function to find a term in the Fibonacci series.

When I try to run it I get the following error:

error: expected '(' for function-style cast or type construction

Can somebody please give me a way forward or ideas on how to proceed?

Answer Source

I agree with @101010 that this is a unusual way of benchmarking a software.

That said, here is a solution that works also with functions havingvoid return type (the example in the question wouldn't have worked with them):


struct Check {
    Check(): time1{std::chrono::high_resolution_clock::now()} {}

    ~Check() {
        std::chrono::high_resolution_clock::time_point time2 = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(time2 - time1).count();
        std::cout << duration << " milliseconds" << std::endl;

    std::chrono::high_resolution_clock::time_point time1;

template<typename F, typename... Tail>
typename std::result_of<F(Tail&&...)>::type measureAndExecute(F f, Tail&&... tail) {  
    Check check;
    return f(std::forward<Tail>(tail)...);

int f(int i) { return i; }
void g() { }

int main() {
    measureAndExecute(f, 42);

The basic idea is to create an instance of Check and exploit its lifetime to measure the time.


As mentioned in the comments, a refinement of measureAndExecute would be:

template<typename F, typename... Tail>
typename std::result_of<F&&(Tail&&...)>::type measureAndExecute(F &&f, Tail&&... tail) {  
    Check check;
    return std::forward<F>(f)(std::forward<Tail>(tail)...);