c++ - ¿Son legales los objetos infinitos std:: chrono:: duration?
c++11 language-lawyer (2)
¿Es legal hacer y usar std::chrono::duration<double>
con un valor infinito como valor contenido, como eso?
std::chrono::duration<double>{ std::numeric_limits<double>::infinity() };
¿Se comportará ''como espero'', manteniendo un valor infinito al sumar o restar con otras duraciones?
He investigado en cppreference pero lo único que encontré al discutir la pregunta es la página duration_cast
-cast que señala que:
La conversión de una duración de punto flotante a una duración de entero está sujeta a un comportamiento indefinido cuando el valor de punto flotante es NaN, infinito o demasiado grande para ser representable por el tipo entero del objetivo. De lo contrario, la conversión a una duración de entero está sujeta a truncamiento como con cualquier static_cast a un tipo entero.
lo que parece dar a entender que es legal, pero solo de una manera indirecta.
(Estoy usando el tipo para representar una manera de "Por favor, despiértame en X segundos", y el infinito positivo es un centinela útil para representar "Realmente no me importa cuando me despierto")
El valor infinity
para std::chrono::duration<double>
se comportará como espera con los operadores aritméticos.
std::chrono::duration<double>
está perfectamente bien
[time.duration] define las condiciones existentes en Rep
para la template<class Rep> std::chrono::duration
y se permite explícitamente el double
(por [time.duration]/2 ), no se rechaza ningún valor especial:
Rep
será un tipo aritmético o una clase que emule un tipo aritmético.
std::numeric_limits<double>::infinity()
está perfectamente bien
[time.duration.arithmetic] y [time.duration.nonmemberdefine] definen el comportamiento de los operadores aritméticos en la duration
. Para cada operator♦
y dados dos objetos de duration
A
y B
sostienen los valores double
a
y b
, A♦B
efectos como a♦b
. Por ejemplo para +
:
En las descripciones de funciones que siguen,
CD
representa el tipo de retorno de la función.CR(A, B)
representacommon_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);
Devuelve:
CD(CD(lhs).count() + CD(rhs).count())
.
Esto significa explícitamente que lo siguiente se comportará como se espera:
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 };
La característica duration_values
tiene un valor max()
para ese propósito:
std::chrono::duration<double>::max();
No uses el infinity
. En caso de que, en el futuro, convierta esa duración a un tipo basado en enteros, puede terminar con UB.