任意功能的计时器

眼睛的树

我试图构建一个可以测量任意类型的函数执行时间的函数模板。到目前为止,这是我尝试过的:

#include <chrono>
#include <iostream>
#include <type_traits>
#include <utility>

// Executes fn with arguments args and returns the time needed
// and the result of f if it is not void
template <class Fn, class... Args>
auto timer(Fn fn, Args... args)
    -> std::pair<double, decltype(fn(args...))> {
  static_assert(!std::is_void<decltype(fn(args...))>::value,
                "Call timer_void if return type is void!");
  auto start = std::chrono::high_resolution_clock::now();
  auto ret = fn(args...);
  auto end = std::chrono::high_resolution_clock::now();
  std::chrono::duration<double> elapsed_seconds = end - start;
  return { elapsed_seconds.count(), ret };
}

// If fn returns void, only the time is returned
template <class Fn, class... Args>
double timer_void(Fn fn, Args... args) {
  static_assert(std::is_void<decltype(fn(args...))>::value,
                "Call timer for non void return type");
  auto start = std::chrono::high_resolution_clock::now();
  fn(args...);
  auto end = std::chrono::high_resolution_clock::now();
  std::chrono::duration<double> elapsed_seconds = end - start;
  return elapsed_seconds.count();
}

int main () {
    //This call is ambigous if the templates have the same name
    std::cout << timer([](double a, double b){return a*b;},1,2).first;
}

请注意,我必须拥有一个功能不同的void(...)功能。有什么办法可以摆脱第二个功能?

(首先我做了什么纠正?)

斯巴比

您可以使用enable_if或标记调度。Enable_if在这种情况下,似乎是更快的方法:

#include <type_traits>

template <class Fn, class... Args>
auto timer(Fn fn, Args && ... args) -> typename std::enable_if< 
    // First template argument is the enable condition
    !std::is_same< 
            decltype( fn( std::forward<Args>(args) ... )), 
            void >::value,
    // Second argument is the actual return type
    std::pair<double, decltype(fn(std::forward<Args>(args)...))> >::type
{
   // Implementation for the non-void case
}

template <class Fn, class... Args>
auto timer(Fn fn, Args &&... args) -> typename std::enable_if< 
    std::is_same< 
            decltype( fn( std::forward<Args>(args) ... )), 
            void >::value,
    double>::type
{
   // Implementation for void case
}

另外,您应该使用完美转发将参数传递给被调用的函数:

 auto timer(Fn fn, Args && ... args) // ...
                      ~~~^   

当您调用该函数时:

 auto ret = fn( std::forward<Args>(args)...);

演示注意,这适用于函数,lambda和可调用对象。几乎所有的东西operator()

从设计的角度来看,返回没问题std::pair由于C ++ 11具有std::tie,所以返回pair/tuple是从函数返回多个结果的合法方法。我要说的是,为了保证void情况的一致性,您应该返回仅包含一个元素的元组。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

任意功能的计时器

来自分类Dev

设置功能的计时器

来自分类Dev

Javascript计时器功能

来自分类Dev

当计时器运行的功能下降时?

来自分类Dev

计时器实现超时功能

来自分类Dev

如何创建计时器功能?

来自分类Dev

计时器功能的错误处理

来自分类Dev

计时器实现超时功能

来自分类Dev

javascript setTimeout计时器步进功能

来自分类Dev

UWP 中相机功能的计时器

来自分类Dev

如何为CSS动画计时功能设置计时器?

来自分类Dev

Azure功能计时器触发器

来自分类Dev

如何在按下空格键或键盘上的任意键的计时器中停止计时器?

来自分类Dev

甜蜜警报计时器-完成功能

来自分类Dev

如何使用其他功能停止计时器

来自分类Dev

计时器功能发生错误(MATLAB R2014a)

来自分类Dev

无法将按钮的值传递到计时器功能

来自分类Dev

计时器功能扭曲可拖动的线段

来自分类Dev

功能中的计时器刷新页面

来自分类Dev

小型纸牌游戏需要计时器或延迟功能

来自分类Dev

计时器触发的Azure功能无法正常执行

来自分类Dev

计时器功能不会接受其他参数

来自分类Dev

仅使用React挂钩的功能齐全的倒数计时器

来自分类Dev

Linux关于设置计时器功能的问题

来自分类Dev

如何向功能添加计时器-iOS Swift

来自分类Dev

与计时器一起使用Catch返回功能

来自分类Dev

使用计时器获取功能的运行时

来自分类Dev

计时器功能发生错误(MATLAB R2014a)

来自分类Dev

如何重置和设置计时器功能?