2

我有以下 Timer 类来简化获取自一个纪元以来经过的时间:

#include <chrono>

class Timer {
  public:
    void start(void);
    template <typename duration_type>
    const duration_type time_elapsed(void);
  private:
    std::chrono::high_resolution_clock::time_point epoch;
};

void Timer::start(void) {
  epoch = std::chrono::high_resolution_clock::now();
}

template <typename duration_type>
const duration_type Timer::time_elapsed(void) {
  return std::chrono::duration_cast<duration_type>(std::chrono::high_resolution_clock::now() - epoch);
}

int main(void) {
  Timer timer;

  timer.start();

  // pointless loop to cause a delay
  for (int x = 1; x < 1000000; ++x) {
    x * x * x;
  }

  std::chrono::nanoseconds elapsed = timer.time_elapsed<std::chrono::nanoseconds>();
  std::cout << elapsed.count() << std::endl;

  return 0;
}

我有一种感觉,通过使 Timer::time_elapsed() 成为模板函数,我的课程过于复杂,并且理想情况下希望将其用法简化为以下内容:

  std::chrono::nanoseconds elapsed = timer.time_elapsed();
  std::cout << elapsed.count() << std::endl;
4

2 回答 2

4

我在您的代码中修复了一些问题,并添加了std::chrono. 更改列表包括:

  1. (void)从函数调用中删除了所有参数,因为它不是 C++ 方式:-)
  2. 我还删除return 0;main()C++ 中不需要的内容,因为编译器会为您提供它。
  3. 我输入了一个时钟,因为现在很难在当前的实现中找到一个高质量的时钟。在这里查看我的答案。基本上现在您可能想要使用您的自定义时钟,并且由于typedef重构,将来可能会更容易。
  4. 我将您的等待循环更改为 C++11 睡眠接口(如果需要,您可以在那里随机化一些持续时间 - 也可以使用 C++11 :-))。在那种情况下不需要这种改变,但它很好地展示了如何std::chrono在线程库中使用。
  5. 我将您的方法实现放在一个类中,以使编译器有机会内联它们。或者,您可以inline在类之外的实现中使用关键字显式。
  6. 我做了你的time_elapsed()方法const
  7. const从方法的返回值中删除了不必要的time_elapsed(),另一方面在使用该方法时添加了它,因为在那个确切的地方const就足够了。
  8. 最后但并非最不重要的一点是,我修改了您的time_elapsed()方法以在return. 这是更好的解决方案,因为您永远不会在这里丢失数据。在以特定单位(即我们)向用户提供数据时,您可能希望松开它。你必须用duration_cast那里告诉编译器你同意丢失一些数据,我们的解决方案对你来说就足够了。

我希望下面的代码和上面的更改对您来说会很有趣。

#include <chrono>
#include <thread>
#include <iostream>

using namespace std::chrono;

class Timer {
public:
  typedef high_resolution_clock Clock;
  void start()
  { epoch = Clock::now(); }
  Clock::duration time_elapsed() const
  { return Clock::now() - epoch; }
private:
  Clock::time_point epoch;
};

int main() {
  Timer timer;
  timer.start();

  // sleep some time
  std::this_thread::sleep_for(microseconds(40));

  const auto elapsed = timer.time_elapsed();
  std::cout << duration_cast<microseconds>(elapsed).count() << "us" << std::endl;
}

顺便说一句,我不想​​玩类界面(我已经做了太多更改)。如果您尚未绑定到该界面,我建议您遵循@sehe 建议的界面。但不要将其double用作返回值 ;-)

于 2012-11-17T18:31:42.880 回答
1

返回一个辅助类,该类存储 now-epoch() 并从经过的时间开始对运算符 T 进行高精度转换。或者,有一个time_elapsed_in_units<T>看起来像你的时间已经过去的方法,然后让时间过去返回一个结构,该结构以运算符 T 为单位调用。

辅助类的操作符 T 的重载让您可以隐式检测被调用者想要什么类型。

于 2012-11-17T14:08:08.610 回答