Is it legal to make and use std::chrono::duration<double>
's with an infinity as the contained value, like so?
std::chrono::duration<double>{ std::numeric_limits<double>::infinity() };
Will it behave 'like I expect', keeping an infinite value when adding or subtracting with other durations?
I've dug through cppreference but the only thing I've found discussing the question is the page on duration_cast
noting that:
Casting from a floating-point duration to an integer duration is subject to undefined behavior when the floating-point value is NaN, infinity, or too large to be representable by the target's integer type. Otherwise, casting to an integer duration is subject to truncation as with any static_cast to an integer type.
which seems to imply that it's legal, but only in a backhanded sort of way.
(I'm using the type to represent a "Please wake me up in X seconds" way, and positive infinity is a useful sentinel to represent "I really don't care when I wake up")
Class template std::chrono::duration represents a time interval. It consists of a count of ticks of type Rep and a tick period, where the tick period is a compile-time rational fraction representing the time in seconds from one tick to the next. The only data stored in a duration is a tick count of type Rep .
std::chrono::secondsInstantiation of duration to represent seconds.
The value infinity
for std::chrono::duration<double>
will behave as you expect with arithmetic operators.
std::chrono::duration<double>
is perfectly fine[time.duration] defines the conditions existing on Rep
for template<class Rep> std::chrono::duration
and double
is explicitly allowed (per [time.duration]/2), no special value disallowed:
Rep
shall be an arithmetic type or a class emulating an arithmetic type.
std::numeric_limits<double>::infinity()
is perfectly fine[time.duration.arithmetic] and [time.duration.nonmemberdefine] define the behaviour of the arithmetic operators on duration
. For each operator♦
and given two duration
objects A
and B
holding the double
values a
and b
, A♦B
effects as a♦b
would. For instance for +
:
In the function descriptions that follow,
CD
represents the return type of the function.CR(A, B)
representscommon_type_t<A, B>
.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);
Returns:
CD(CD(lhs).count() + CD(rhs).count())
.
This explicitly means that the following will behave as expected:
const double infinity = std::numeric_limits<double>::infinity(); std::chrono::duration<double> inf{ infinity }; std::chrono::duration<double> one{ 1.0 }; inf + one; // as if std::chrono::duration<double>{ infinity + 1.0 };
The duration_values
trait has a max()
value for that purpose:
std::chrono::duration<double>::max();
Don't use infinity
. Should you happen to convert such a duration to an integer-based type in the future, you can end up with UB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With