c++voidreturn-type-deduction

C++ Assign a variable to function call that could return void


I'm trying to write a function that measures the time of execution of other functions. It should have the same return type as the measured function. The problem is that i'm getting a compiler error Variable has incomplete type 'void' when the return type is void. Is there a workaround to solve this problem? Help would be greatly appreciated, thanks!

#include <iostream>
#include <chrono>

template<class Func, typename... Parameters>
auto getTime(Func const &func, Parameters &&... args) {
    auto begin = std::chrono::system_clock::now();
    auto ret = func(std::forward<Parameters>(args)...);
    auto end = std::chrono::system_clock::now();
    std::cout << "The execution took " << std::chrono::duration<float>(end - begin).count() << " seconds.";
    return ret;
}

int a() { return 0; }
void b() {}

int main()
{
    getTime(a);
    getTime(b);
    return 0;
}

Solution

  • It's possible to solve this problem using specialization and an elaborate song-and-dance routine. But there's also a much simpler approach that takes advantage of return <void expression>; being allowed.

    The trick is to fit it into this framework, by taking advantage of construction/destruction semantics.

    #include <iostream>
    #include <chrono>
    
    struct measure_time {
    
        std::chrono::time_point<std::chrono::system_clock> begin=
            std::chrono::system_clock::now();
    
        ~measure_time()
        {
            auto end = std::chrono::system_clock::now();
            std::cout << "The execution took "
                  << std::chrono::duration<float>(end - begin).count()
                  << " seconds.\n";
        }
    };
    
    
    template<class Func, typename... Parameters>
    auto getTime(Func const &func, Parameters &&... args) {
    
        measure_time measure_it;
    
        return func(std::forward<Parameters>(args)...);
    }
    
    int a() { return 0; }
    void b() {}
    
    int main()
    {
        getTime(a);
        getTime(b);
        return 0;
    }