c++ c++11 language-lawyer chrono

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) representa common_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.