我会这样做:
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>
实用程序列表。<chrono>
请随意使用它们,将它们推荐给您的标准机构代表,或自己提出。
更新
当我写上面的内容时,我已经离开了我的游戏。我不会删除它,因为它为我自己和其他人提供了关于如何不编写chrono
实用程序的一个很好的教训。
我不喜欢它的地方:
它通过直接操作Rep
.
它假定文字 0 可以隐式转换为,或至少与 . 相当Rep
。
没有理由不这样做constexpr
。
我对 unsigned 的行为不满意Rep
。如果有人说:
自动 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>
abs(std::chrono::duration<Rep, Period> d)
{
return d >= d.zero() ? d : -d;
}
duration
有 unary -
,只需使用它。
duration
具有可自定义的zero
特征,因此不必假设与0
from密切合作Rep
。就用它吧。
使用的所有操作都constexpr
标abs
有constexpr
。
静态函数min
和zero
是constexpr
。使用这些来确定是否Rep
已签名比使用诸如!std::is_unsigned
. 即Rep
可能是 aBigNum
或 C11 timespec
(增加了重载的算术运算符)。所以“已签名”的问题是用 来回答的min() < zero()
。而现在这个版本abs
将不接受一个duration<unsigned, milli>
(例如)。