[オリジナル] C ++の新しい標準std :: chrono :: duration
元の要約C ++ 11クロノ持続時間比
概要概要
新しいC ++標準は、新しいスレッドライブラリを提供します。最近、テストコードを作成するときは、現在のスレッドをスリープ状態にする必要があります。Windowsが提供するSleep()を直接呼び出すだけです。新しい標準では、std :: this_threadを使用できます。:: sleep_for()またはstd :: this_thread :: sleep_until()
を使用して、スリープを実現します。これには、std :: chrono :: durationとstd :: chrono :: time_pointが含まれます。この記事はstd :: chrono :: durationのみを要約し、std :: chrono :: time_pointは別の要約を書き込みます。
std :: chrono :: duration
説明
std :: chrono :: durationはファイルで定義され、期間を表すために使用されます。
cppreferenceの元の単語は次のとおりです。
クラステンプレートstd :: chrono :: durationは時間間隔を表します。
これは、タイプRepのティック数とティック期間で構成されます。ティック期間は、 あるティックから次のティックまでの秒数を表すコンパイル時の有理定数 です。
期間に保存される唯一のデータは、タイプRepのティックカウントです。Repが浮動小数点の場合、期間はティックの端数を表すことができます。期間は期間のタイプの一部として含まれ、異なる期間間で変換する場合にのみ使用されます。
Rep
このパラメーターは、渡すことができる時間単位のタイプを表します。これには、float、int、int64などがあります。floatの場合は、時間単位の一部を渡すことができることを意味します。たとえば、渡す1.2は、時間単位の1.2倍を意味します。Period
パラメータは時間単位を表し、マイクロ秒、ミリ秒、秒、分、時間などになります(または他のカスタム単位の場合、タイプはstd :: ratioです)。
注意:
- 上記のティックは、期間または時間の単位として理解できます。
- 秒数は 、期間値が秒に基づいて計算されることを示します。
クラス定義
std :: chrono :: durationはテンプレートクラスです。キーコードは次のように抜粋されています(形式が調整されています)。
template<class _Rep, class _Period>
class duration {
public:
typedef duration<_Rep, _Period> _Myt;
typedef _Rep rep;
typedef _Period period;
// constructor, save param to _MyRep, used by count() member function.
template<class _Rep2,
class = typename enable_if<is_convertible<_Rep2, _Rep>::value
&& (treat_as_floating_point<_Rep>::value || !treat_as_floating_point<_Rep2>::value),
void>::type>
constexpr explicit duration(const _Rep2& _Val)
: _MyRep(static_cast<_Rep>(_Val))
{
}
constexpr _Rep count() const { return (_MyRep); }
};
// convert duration from one unit to another.
template<class _To, class _Rep, class _Period> inline
constexpr typename enable_if<_Is_duration<_To>::value, _To>::type
duration_cast(const duration<_Rep, _Period>& _Dur)
{
typedef ratio_divide<_Period, typename _To::period> _CF;
typedef typename _To::rep _ToRep;
typedef typename common_type<_ToRep, _Rep, intmax_t>::type _CR;
#pragma warning(push)
#pragma warning(disable: 6326) // Potential comparison of a constant with another constant.
return (_CF::num == 1 && _CF::den == 1
? static_cast<_To>(static_cast<_ToRep>(_Dur.count()))
: _CF::num != 1 && _CF::den == 1
? static_cast<_To>(static_cast<_ToRep>(
static_cast<_CR>(
_Dur.count()) * static_cast<_CR>(_CF::num)))
: _CF::num == 1 && _CF::den != 1
? static_cast<_To>(static_cast<_ToRep>(
static_cast<_CR>(_Dur.count())
/ static_cast<_CR>(_CF::den)))
: static_cast<_To>(static_cast<_ToRep>(
static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num)
/ static_cast<_CR>(_CF::den))));
#pragma warning(pop)
}
duration_cast()分析
この関数duration_cast()
は、異なる時間単位間で変換する機能を提供します。
duration_cast()
主に2つの部分に分かれています:
-
ratio_divide
より定義された比別に変換比の変換率。
以下のような変換比である((1/10 /(2/5))= 1/4)と言うことである、同等のものを。コードに対応します。1/10
2/5
1/4
1/10
1/4
2/5
_CF::num = 1, _CF::den = 4
-
変換率(returnステートメント)に従って、n単位の元のデータをターゲットデータに変換します。
return
文は効率のために非常に複雑に記述されており、不要な乗算と除算を回避します。分子が1の場合、乗算する必要はありません。分母は1です。除算する必要はありません。
それを(強制せずに)単純化することは次のとおりです。return _Dur.count() * (_CF::num / _CF::den);
人気話す:場合A
にB
変換の割合num/den
は、1
1がA
に変換することができますnum/den
2 B
、 n
1をA
に変換することができます n * (num/den)
1 B
。
注:vsに付属のソースコードは実際には読みにくいです。ブーストソースコードを参照することをお勧めします。
事前定義された期間
コードを書くのに便利なように、事前定義されたいくつかの一般的に使用される時間単位と比較して、抜粋は次のとおりです。
- typedef duration <long long、nano>ナノ秒; //ナノ秒
- typedef期間<longlong、micro>マイクロ秒; //微秒
- typedef duration <long long、milli>ミリ秒; //毫秒
- typedef duration <longlong>秒; //秒
- typedef期間<int、比率<60 >>分; //分钟
- typedef期間<int、比率<3600 >>時間; //小時間
上記の定義によればstd::chrono::microseconds
、定義内のRep
型はlong long
であり、Period
型はであることがわかりますmilli
。
注:
std::chrono::microseconds
定義Rep
の型がであるため、long long
次の方法では100.5ミリ秒スリープできませんstd::this_thread::sleep_for(std::chrono::microseconds(100.5));
。型が一致しない場合、コンパイルエラーが報告されます。100.5ミリ秒スリープしたい場合は、次のように記述できます。std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(100.5f));
サンプルコード
例1:分をミリ秒に変換する
#include <iostream>
#include <chrono>
int main()
{
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::minutes(3));
std::cout << "3 minutes equals to " << ms.count() << " milliseconds\n";
std::cin.get();
}
例2.カスタム単位変換
#include <iostream>
#include <chrono>
typedef std::chrono::duration<float, std::ratio<3, 1> > three_seconds;
typedef std::chrono::duration<float, std::ratio<1, 10> > one_tenth_seconds;
int main()
{
three_seconds s = std::chrono::duration_cast<three_seconds>(one_tenth_seconds(3));
std::cout << "3 [1/10 seconds] equal to " << s.count() << " [3 seconds]\n";
std::cin.get();
}
例3.100ミリ秒スリープします
#include <thread>
#include <chrono>
int main()
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// or
std::this_thread::sleep_for(std::chrono::duration<long long, std::milli>(100));
// or
// typedef ratio<1, 1000> milli;
std::this_thread::sleep_for(std::chrono::duration<long long, std::ratio<1, 1000> >(100));
}