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:
Repshall 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,
CDrepresents 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