c++ - std::chrono::duration 对象的绝对值

标签 c++ c++11 c++-chrono

鉴于 std::chrono::duration 可以表示两个时间之间的带符号差值,因此需要此类持续时间的绝对值似乎是一种非常常见的情况。例如,以下代码按预期输出 diff: -5:

using namespace std;
using namespace std::chrono;

auto now = system_clock::now();
auto then = now - seconds(5);
auto diff = then - now;

cout << "diff: " << duration_cast<seconds>(diff).count() << endl;

如果能做这样的事情就好了:

auto diff = abs(then - now);

但是,我在标准中看不到 std::abschrono 模板的任何特化,也看不到 中任何适当的成员函数>std::chrono::duration.

我应该如何将 std::chrono::duration 转换成它的绝对值?

最佳答案

我会这样做:

template <class Rep, class Period>
std::chrono::duration<Rep, Period>
abs(std::chrono::duration<Rep, Period> d)
{
    Rep x = d.count(); 
    return std::chrono::duration<Rep, Period>(x >= 0 ? x : -x);
}

查看我的 <chrono> Utilities 列表,了解我希望成为标准的其他 <chrono> 实用程序。请随意使用它们,将它们推荐给您的标准机构代表,或者您自己提出。

更新

当我写以上内容时,我不在游戏中。我不会删除它,因为它为我自己和其他人提供了一个很好的教训,告诉他们如何编写 chrono 实用程序。

我不喜欢它的地方:

  1. 它通过直接操纵 Rep 不必要地降低类型安全。

  2. 它假定文字 0 可以隐式转换为 Rep,或者至少可以与 constexpr 进行比较。

  3. 没有理由不是 Rep

  4. 我对 unsigned t1 的行为不满意。如果有人说:

    自动 d = abs(t1 - t0);

t0t1 < t0是基于unsigned duration的,那么这很可能是代码中的逻辑错误。如果是 abs ,那么您可能会得到一个不正确的、非常长的持续时间。如果那是您真正想要的,那么您不应该使用 abs ,而是编写更简单的代码:

   auto d = t1 - t0;

为了解决这些问题,我将持续时间的 duration 重写为:

template <class Rep, class Period,
          class = typename std::enable_if
          <
              std::chrono::duration<Rep, Period>::min() <
              std::chrono::duration<Rep, Period>::zero()
          >::type
         >
constexpr
inline
std::chrono::duration<Rep, Period>
abs(std::chrono::duration<Rep, Period> d)
{
    return d >= d.zero() ? d : -d;
}
  1. - 有一元 duration ,随便用吧。

  2. zero 具有可定制的 0 特性,因此您不必假设与 Rep 中的 constexpr 密切合作。就用它吧。

  3. 使用的所有操作都是 abs ,用 constexpr 标记 min

  4. 静态函数 zeroconstexprRep 。使用这些来确定 !std::is_unsigned 是否已签名比使用 Rep 等特征更通用。 IE。 BigNum 可能是 timespec 或 C11 min() < zero()(用重载算术运算符增强)。所以问题“已签名”用 abs 回答。现在这个版本的 duration<unsigned, milli> 将不接受 ojit_code(例如)。

关于c++ - std::chrono::duration 对象的绝对值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21321445/

相关文章:

c++ - std::chrono time_since_epoch 的默认持续时间

c++ - 包括时区的 chrono 解析

c++ - 预处理器定义在 VS2019 C++ 中不起作用

c++ - 从文本文件 : weird behaviour 中读取单词

c++ - "while"循环在应该结束时没有结束

c++ - 没有可用于带有初始值设定项的静态常量成员的定义?

C++ 使用 std::chrono 以一种很好的方式测量成员函数的执行

c++ - 为什么这段代码用 g++ 编译需要这么长时间?

c++ - 调用没有对象参数编译器错误的非静态成员函数

c++ - 错误 C2783 : '_Ty &&std::forward(remove_reference<_Ty>::type &&) throw()' : could not deduce template argument for '_Ty'