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

1

6

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;
}
Surround answered 3/9, 2022 at 23:11 Comment(5)
This doesn't make a lot of sense. The fn return type isn't void. void means the fn has no return type. If you're writing something that needs a return value then a fn with no return value won't work.Sturdivant
Is there a workaround to solve this problem? - For example, return func(...); + RAII.Mellisa
void means no value or nothing - how would you assign anything to "nothing"??Highwayman
I am trying to make this function general enough to work with all kinds of functions, while forwarding the returned value (if it exists). Surely I am gonna discard the return value if it is void, but otherwise it is helpful to pass it on.Surround
return void(); is a thing. And for void foo(); you can return foo(); for a return type of void.Frydman
K
8

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;
}
Krakow answered 3/9, 2022 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.