首页 > 解决方案 > 我应该使用高分辨率时间类型作为参数来避免 duration_casts 吗?

问题描述

我读到,如果您的程序使用的最高分辨率类型是,milliseconds并且这种类型将覆盖您的值所在的整个范围,那么您应该主要坚持使用它,以避免duration_casts无处不在。相反,如果您需要的只是一个精度,那么在函数内部您将只有一个,比如说seconds.

但是,对于函数的返回类型,您将相反地返回可能的最低分辨率,以获得尽可能低的 duration_casts 数量(这里甚至是最佳性能,因为在这种情况下无论如何您都会进行转换)。

不幸的是,我没有找到全面(或以任何方式)涵盖此问题的来源。这是std::chrono应该使用的方式吗(假设一个人不急于最后可能的表现)?

标签: c++type-conversionimplicit-conversionchrono

解决方案


我认为关于这个策略一般没有什么可以说的,除了的,你不想在你的代码中不必要地乱扔duration_cast. 仅保留duration_cast那些要截断精度的转换。并且在这些情况下,认识到它会duration_cast向零截断。C++17 引入了另外 3 种截断策略:

  • floor: 向负无穷大截断
  • ceil: 向正无穷大截断
  • round: 向最近的方向截断,甚至在领带上截断

(如果您使用 C++11/14,您可以在此处获取这些方便的实用程序)。

当然,如果milliseconds是您想要处理的最佳精度,则将其milliseconds作为参数类型是一个很好的策略。

对返回类型使用较粗的精度可能对某些应用程序有好处,但可能并非对所有应用程序都适用。考虑:

seconds process(milliseconds input);

process是一些函数,它接受 a duration input,对其执行一些操作,然后返回duration输出。在此示例中,我选择了比输入 ( seconds) 更粗略的精度。据推测,在某些时候我已经截断了输入的精度,并且在此过程中丢失了信息。

现在,如果 的目的process是截断精度,这完全没问题。但是,如果目的process是别的,而您只是返回seconds以便客户可以执行以下任一操作:

milliseconds result1 = process(input);
seconds      result2 = process(input);

那么你可能不会给客户任何好处。当然,获取的语法result2非常简洁。但是您也取消了该客户端在截断方向上的选择(向下、向上、最近等)。也许这对您的应用程序来说是件好事。但这对每个人来说都不是一件好事,因此对于通用库来说也不是。

作为另一个例子,让我们看看其中一个函数<chrono>本身的返回类型:

template<class Rep1, class Period1, class Rep2, class Period2>
constexpr
common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
operator+(const duration<Rep1, Period1>& lhs,
          const duration<Rep2, Period2>& rhs);

在此示例中,函数 ( )从其输入中operator+返回最精细的精度,而不是最粗略的,以努力不丢失任何信息。如果需要,客户端可以自由截断该结果。对于不熟悉的人来说common_type_t,这与:

constexpr
milliseconds
operator+(const seconds& lhs, const milliseconds& rhs);

推荐阅读