代わりに std::chrono::nanoseconds を使用する場合、たとえば 10 分と指定するのは面倒です。
実際、少なくとも面倒なことはありません。
#include <chrono>
#include <iostream>
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
{
std::cout << timeout.count() << '\n';
}
int main()
{
my_function(true, std::chrono::minutes(10));
}
出力:
600000000000
問題が発生するのは、 , または(1/3 秒単位)など、nanoseconds
に正確に変換されないものを渡したい場合だけです。nanoseconds
picoseconds
duration<long, ratio<1, 3>>
アップデート
私は、この回答が、(sehe による) 良い回答だと思った、既に受け入れられている回答の追加情報であることを意図していました。sehe はテンプレート化されたソリューションを推奨しましたが、これも問題ないと思います。
切り捨てたり丸めたりする必要がある可能性のあるものであっても、受け入れ たい場合は、seheの削除された回答を使用するのが方法です:std::chrono::duration
template <typename Rep, typename Period>
void my_function(bool work_really_hard, std::chrono::duration<Rep, Period> timeout)
{
// Do stuff, until timeout is reached.
std::this_thread::sleep_for(timeout);
}
何らかの理由でテンプレートを扱いたくない場合、および/または に正確に変換できる単位のみをクライアントに指定させることに満足している場合は、上で示したようにstd::chrono:nanoseconds
使用std::chrono:nanoseconds
することも完全に受け入れられます。
すべてのstd::chrono
「定義済み」単位:
hours
minutes
seconds
milliseconds
microseconds
nanoseconds
は暗黙的に に変換可能nanoseconds
であり、切り捨てや丸めエラーは発生しません。2 本の明るい白線の範囲内に収まっている限り、オーバーフローは発生しません (自分の車線を維持することへのあいまいな言及)。期間が +/- 292 年以内であれば、これらの事前定義された単位でのオーバーフローを心配する必要はありません。
のような標準定義関数std::this_thread::sleep_for
は、考えられるすべてのものと相互運用できるようにしたいという正確な理由で、sehe が示唆するようにテンプレート化されていますchrono:duration
(たとえば、浮動小数点フェムト秒の 1/3)。独自の API にそれほどの柔軟性が必要かどうかを判断するのは、API 設計者次第です。
明確にする代わりに混乱させてしまったとしても、あまり心配しないでください。を使用することを選択した場合nanoseconds
、切り捨てや丸めエラーなしで正確に機能するか、クライアントでコンパイル時エラーが発生します。実行時エラーは発生しません。
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
{
std::cout << timeout.count() << '\n';
}
int
main()
{
using namespace std;
using namespace std::chrono;
typedef duration<double, pico> picoseconds;
my_function(true, picoseconds(100000.25));
}
test.cpp:15:9: error: no matching function for call to 'my_function'
my_function(true, picoseconds(100000.25));
^~~~~~~~~~~
test.cpp:4:10: note: candidate function not viable: no known conversion from 'duration<double, ratio<[...], 1000000000000>>' to
'duration<long long, ratio<[...], 1000000000>>' for 2nd argument
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
^
1 error generated.
クライアントがコンパイル時エラーを受け取った場合、クライアントはいつでもduration_cast
それを回避するために使用できます。
my_function(true, duration_cast<nanoseconds>(picoseconds(100000.25))); // Ok
詳細については、次を参照してください。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm
この回答の上部にある元のコードを更新してください。C++1y では、C++14 を意味することを願っています。
using namespace std::literals;
my_function(true, 10min); // also ok, is equal to 600000000000 nanoseconds
質問:「無限」のタイムアウトとして何をお勧めしますか (つまり、タイムアウトしないでください)。
私は最初に、タイムアウトを取らず、「タイムアウトしない」ことを意味する API を使用しようとしました。たとえばcondition_variable::wait
。API を制御できれば、タイムアウトなしでそのような署名を作成できます。
それができない場合は、「大規模」なシリーズを作成しますchrono::durations
。
using days = std::chrono::duration
<
std::int32_t, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>
>;
using weeks = std::chrono::duration
<
std::int32_t, std::ratio_multiply<days::period, std::ratio<7>>
>;
using years = std::chrono::duration
<
std::int32_t, std::ratio_multiply<days::period, std::ratio<146097, 400>>
>;
using months = std::chrono::duration
<
std::int32_t, std::ratio_divide<years::period, std::ratio<12>>
>;
次に、通話でこれらの長い期間のいずれかを使用します。たとえば、次のようになります。
std::this_thread::sleep_for(years(3));
push_things を最大限にしようとはしません (たとえば、OS が行った根本的な仮定を破る可能性があります)。途方もなく大きなもの (3 年など) を任意に選択するだけです。これはコード レビュー担当者の目を引き、有益な会話を開始する可能性があります。:-)
ビデオで利用できるようになりました: https://www.youtube.com/watch?v=P32hvk8b13M :-)