C ++ 11 std :: chrono :: duration

[オリジナル] C ++の新しい標準std :: chrono :: duration

元の要約C ++ 11クロノ持続時間比 

 

概要概要

新しいC ++標準は、新しいスレッドライブラリを提供します。最近、テストコードを作成するときは、現在のスレッドをスリープ状態にする必要があります。Windows提供するSleep()を直接呼び出すだけです。新しい標準では、std :: this_threadを使用できます。:: sleep_for()またはstd :: this_thread :: sleep_until()
を使用して、スリープを実現します。これには、std :: chrono :: durationstd :: 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です)。

注意:

  1. 上記のティックは、期間または時間の単位として理解できます。
  2. 秒数は 、期間値が秒に基づいて計算されることを示します。

クラス定義

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/102/51/4 1/101/42/5
    _CF::num = 1, _CF::den = 4

  • 変換率(returnステートメント)に従って、n単位の元のデータをターゲットデータに変換します。
    return文は効率のために非常に複雑に記述されており、不要な乗算と除算を回避します。分子が1の場合、乗算する必要はありません。分母は1です。除算する必要はありません。
    それを(強制せずに)単純化することは次のとおりです。
    return _Dur.count() * (_CF::num / _CF::den);

人気話す:場合AB変換の割合num/denは、11がAに変換することができますnum/den2 B、  n1をAに変換することができます n * (num/den)1 B

注:vsに付属のソースコードは実際には読みにくいです。ブーストソースコードを参照することをお勧めします。

事前定義された期間

コードを書くのに便利なように、事前定義されたいくつかの一般的に使用される時間単位と比較して、抜粋は次のとおりです。

  1. typedef duration <long long、nano>ナノ秒; //ナノ秒 
  2. typedef期間<longlong、micro>マイクロ秒; //微秒 
  3. typedef duration <long long、milli>ミリ秒; //毫秒 
  4. typedef duration <longlong>秒; //秒 
  5. typedef期間<int、比率<60 >>分; //分钟 
  6. 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)); 
} 

転載:https//www.cnblogs.com/bianchengnan/p/9478638.html

おすすめ

転載: blog.csdn.net/hyl999/article/details/108006039