c – std :: chrono :: duration对象的绝对值

前端之家收集整理的这篇文章主要介绍了c – std :: chrono :: duration对象的绝对值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
鉴于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);

但是,我看不到标准中chrono模板的std :: abs的任何特化,也没有在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实用程序是一个很好的教训.

我不喜欢的事情:

>通过直接操作Rep来不必要地降低类型安全性.
>它假定文字0可以隐式转换为或至少与Rep相当.
>没有理由这不是constexpr.
>我对未签名的Rep的行为不满意.如果有人说:

auto d = abs(t1-t0);

并且t1和t0基于无符号持续时间,那么这可能是代码中的逻辑错误.如果t1< t0,那么你可能会得到一个不正确的,非常大的持续时间.如果这是你真正想要的,那么你不应该使用abs,而只是编写更简单的代码

auto d = t1 - t0;

为了解决这些问题,我在一段时间内重写了abs:

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> d)
{
    return d >= d.zero() ? d : -d;
}

>持续时间有一元 – 只需使用它.> duration有一个可定制的零特征,只是为了让一个人不必假设与Rep的0密切合作.只需使用它.>所有使用的操作都是constexpr,用constexpr标记为abs.>静态函数min和zero是constexpr.使用这些来确定Rep是否已签名比使用诸如!std :: is_unsigned之类的特征更为通用.即Rep可能是BigNum,也可能是C11 timespec(使用重载算术运算符进行扩充).所以问题“已签名”用min()<零().现在这个版本的abs不接受持续时间< unsigned,milli> (例如).

猜你在找的C&C++相关文章