Являются бесконечными объектами std :: chrono :: duration legal?

Является ли законным создание и использование std::chrono::duration<double> с бесконечностью в качестве содержащегося значения, например?

std::chrono::duration<double>{ std::numeric_limits<double>::infinity() };

Будет ли он вести себя "как я ожидаю", сохраняя бесконечную ценность при добавлении или вычитании с другой продолжительностью?

Я перекопал cppreference, но единственное, что я нашел, обсуждая вопрос, - это страница на duration_cast отмечающая, что:

Кастинг от продолжительности с плавающей запятой до целой продолжительности зависит от неопределенного поведения, когда значение с плавающей запятой является NaN, бесконечность или слишком велико, чтобы быть представимым целевым целым типом. В противном случае приведение к целочисленной длительности может быть усечено, как и любое static_cast для целочисленного типа.

что, по-видимому, подразумевает, что оно является законным, но только в произвольном порядке.

(Я использую тип для представления "Прошу разбудить меня за X секунд", а положительная бесконечность - полезный дозор, чтобы представить "Мне действительно все равно, когда я просыпаюсь")

Ответ 1

Значение infinity для std::chrono::duration<double> будет вести себя так, как вы ожидаете, с помощью арифметических операторов.

std::chrono::duration<double> отлично

[time.duration] определяет условия, существующие в Rep для template<class Rep> std::chrono::duration и double явно разрешено (за [time.duration]/2), никакое специальное значение не разрешено:

Rep должен быть арифметическим типом или классом, эмулирующим арифметический тип.

std::numeric_limits<double>::infinity() отлично работает

[time.duration.arithmetic] и [time.duration.nonmemberdefine] определяют поведение арифметических операторов по duration. Для каждого operator♦ и заданных двух объектов duration A и B содержащих double значения a и b, A♦B эффекты как a♦b будут. Например, для +:

В последующих описаниях функций CD представляет тип возвращаемой функции. CR(A, B) представляет 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);

Возвраты: CD(CD(lhs).count() + CD(rhs).count()).

Это явно означает, что следующее будет вести себя так, как ожидалось:

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 };

Ответ 2

Для этой цели значение duration_values имеет значение max():

    std::chrono::duration<double>::max();

Не используйте infinity. Если вам удастся преобразовать такую длительность в целочисленный тип в будущем, вы можете получить UB.