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:
Repserá 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,
CDrepresenta 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.