我想将一个函数作为参数传递给包装函数,该包装函数执行该函数,计算执行时间并打印出来,然后返回该函数的返回值。这是我到目前为止要做的事情。
#include <functional>
#include <chrono>
namespace TimeIt {
template <typename T>
auto time_it(std::string name, std::function<T> work) -> decltype(work()) {
auto start = std::chrono::high_resolution_clock::now();
auto return_value = work();
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
printf("Time taken by function:%s is %lld",name, duration.count());
return return_value;
}
}
答案 0 :(得分:2)
尝试在此处将所有内容包装在std::function
中是非常有害的,您应该只推导原始可调用类型。
template <typename Callable, typename ... Args>
auto time_it(std::string name, Callable&& work, Args&&... args) -> std::invoke_result_t<Callable, Args...> {
auto start = std::chrono::high_resolution_clock::now();
auto return_value = std::invoke(std::forward<Callable>(work), std::forward<Args>(args)...);
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
printf("Time taken by function:%s is %lld",name, duration.count());
return return_value;
}
答案 1 :(得分:1)
最困难的部分是void
。在这里使用std::function
是有害的,因为它会增加不必要的开销。
template<class F>
struct scope_guard_t {
F f;
~scope_guard_t() noexcept(noexcept(f())
{
f();
}
};
template<class F>
scope_guard_t<std::decay_t<F>> scope_guard(F&&f){
return {std::forward<F>(f)};
}
template<class F>
auto time_it(std::string name, F&& f)
-> std::result_of_t<F&&()>
{
auto start = std::chrono::high_resolution_clock::now();
auto wrapup = scope_guard([&]{
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
printf("Time taken by function:%s is %lld",name, duration.count());
});
return std::forward<F>(f)();
}
我们去了。