试图发送任何函数作为参数和推断类型?

时间:2018-11-09 16:08:36

标签: c++

我想将一个函数作为参数传递给包装函数,该包装函数执行该函数,计算执行时间并打印出来,然后返回该函数的返回值。这是我到目前为止要做的事情。

#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;
}
}

2 个答案:

答案 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)();
}

我们去了。