web-dev-qa-db-ja.com

無限std :: chrono :: durationオブジェクトは合法ですか?

std::chrono::duration<double>を、含まれる値として無限大で作成して使用することは合法ですか?

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

他の期間と加算または減算するときに無限の値を維持して、「期待どおり」に動作しますか?

私はcppreferenceを調べましたが、質問について話し合っているのはduration_castのページで、次のことに注意してください。

浮動小数点の期間から整数の期間へのキャストは、浮動小数点の値がNaN、無限大、またはターゲットの整数型で表現するには大きすぎる場合、未定義の動作の影響を受けます。それ以外の場合、整数期間へのキャストは、整数型へのstatic_castと同様に、切り捨ての対象になります。

これは合法であることを意味しているように見えますが、これはバックハンドでのみ行われます。

(タイプを使用して、「X秒後に起こしてください」という方法を使用しています。正の無限大は、「目を覚ましても気にしない」を表すのに便利なセンチネルです)

28
James Picone

_std::chrono::duration<double>_の値infinityは、算術演算子で期待どおりに動作します。

_std::chrono::duration<double>_は完璧です

[time.duration] は_template<class Rep> std::chrono::duration_のRepに存在する条件を定義し、doubleは明示的に許可されます( [time.duration]ごとに)/2 )、許可されている特別な値はありません:

Repは、算術型または算術型をエミュレートするクラスです。

std::numeric_limits<double>::infinity()は完璧です

[time.duration.arithmetic] および [time.duration.nonmemberdefine] は、durationでの算術演算子の動作を定義します。各_operator♦_に対して、2つのdurationオブジェクトABを保持し、doubleab、_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 };
_
14
YSC

_duration_values_ トレイトには、その目的のためにmax()値があります。

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

infinityは使用しないでください。将来、このような期間を整数ベースの型に変換した場合、UBになる可能性があります。

3
rustyx