C++11標準ライブラリchrono

16025 ワード

chronoは、C++11が新たに追加した便利な日付操作の標準ライブラリであり、対応するヘッダファイル名であり、stdネーミングスペースの下のサブネーミングスペースでもあり、すべての日付関連定義はstd::chronoネーミングスペースの下にある.この新しい標準ライブラリでは、時間と日付に関する操作が非常に便利です.chronoライブラリには主に3つのタイプが含まれています:duration,time_ポイントとclock.
Duration(時間間隔)
chronoライブラリでは、durationテンプレートクラスを使用して、数秒、数分、または数時間の時間間隔を表すことができます.
プロトタイプ
template<typename _Rep, typename _Period = ratio<1>>
struct duration
{
typedef _Rep   rep;
...
private:
    rep  __r;  //           
...
};

最初のテンプレートパラメータは数値タイプで、クロックの個数を表します.2つ目はstd::ratioで、クロックごとの周期(秒単位)を表す.ratioの原型は
template<intmax_t _Num, intmax_t _Den = 1>
struct ratio;

これは非タイプのテンプレートパラメータのテンプレートクラス、intmax_tは、cstdintヘッダファイルに定義される組み込みタイプです.1番目のパラメータは分子を表し、2番目は分母を表し、両者は共通の比率タイプを表す.コンパイル中に定数値として決定する必要があります.分母はデフォルトで1であるため、ratio<60>は60ratio<1, 1000>を0.001として表します.使いやすいようにratioヘッダファイルには、共通比率の別名が定義されています.
  typedef ratio<1, 1000000000000000000> atto;
  typedef ratio<1, 1000000000000000> femto;
  typedef ratio<1, 1000000000000> pico;
  typedef ratio<1, 1000000000> nano;
  typedef ratio<1, 1000000> micro;
  typedef ratio<1, 1000> milli;
  typedef ratio<1, 100> centi;
  typedef ratio<1, 10> deci;
  typedef ratio< 10, 1> deca;
  typedef ratio< 100, 1> hecto;
  typedef ratio< 1000, 1> kilo;
  typedef ratio< 1000000, 1> mega;
  typedef ratio< 1000000000, 1> giga;
  typedef ratio< 1000000000000, 1> tera;
  typedef ratio< 1000000000000000, 1> peta;
  typedef ratio< 1000000000000000000, 1> exa;

durationテンプレートクラスに戻ると、デフォルトの比率はratio<1>、すなわちクロック数です.Repは1秒を表す.使いやすいように、chronoライブラリでは、次のような一般的な時間単位が定義されています.
    /// nanoseconds
    typedef duration<int64_t, nano>     nanoseconds;

    /// microseconds
    typedef duration<int64_t, micro>    microseconds;

    /// milliseconds
    typedef duration<int64_t, milli>    milliseconds;

    /// seconds
    typedef duration<int64_t>       seconds;

    /// minutes
    typedef duration<int, ratio< 60>>   minutes;

    /// hours
    typedef duration<int, ratio<3600>>  hours;

上記の一般的なタイプを定義することで、非常に便利に使用できます.
//    10 
std::this_thread::sleep_for(std::chrono::seconds(10));

メンバー#メンバー#
duration内部では、間隔時間を表すために結合された周期個数repと周期periodが維持されている.
count
内部メンテナンスを取得するために使用されるrepタイプの周期個数、またはtick数と呼ばれる.
chrono::milliseconds ms(10);
chrono::duration<double, std::ratio<1, 30>> dur(10.5);
cout << "ms: " << ms.count() << '\t'<<"dur: "<<dur.count() << endl;

上記コード出力:
ms: 10 dur : 10.5
静的メンバー関数
durationがインスタンス化されると、所与のrepが周期個数を表すタイプに対して、min、max、zeroの3つの静的メンバー関数が提供され、現在のタイプが表すことができる最小、最大周期数、および0周期数が表すdurationオブジェクトを取得する.
cout << chrono::seconds::max().count() << endl;
//9223372036854775807

えんざんさぎょう
durationは、基本的なすべての算術演算操作をサポートし、異なる単位間で自動的にマッチングすることができます.これはduration_castテンプレートクラスによって実現される.
chrono::mimutes t1(5);
chrono::seconds t2(30);
chrono::seconds t3 = t2 - t1;
cout << t3.count << '\t' << chrono::duration_cast<chrono::minutes>(t3).count() << endl;
//           
//    :270 4

Time point
chronoライブラリではtime_pointテンプレートクラスを用いて、誕生日、今日の日没時刻などの時点を表し、epochに対する時間間隔durationによって実現され、epochは1970-1-1時刻であり、同じクロックではtime_pointのepochはすべて固定されている.このクラスは標準ライブラリctimeと組み合わせて時間を表示することができ、ctime内部のtime_tタイプはこの秒数を表す.
プロトタイプ
template<typename _Clock, typename _Dur = typename _Clock::duration>
struct time_point
{
typedef _Clock                      clock;
typedef _Dur                        duration;
typedef typename duration::rep              rep;
typedef typename duration::period           period;
private:
    duration __d; //     duration  
...

};

最初のパラメータは、現在のタイミングで使用されるクロックです.オプションとして、system_colck、steady_colck、high_resolution_clock、またはカスタムクロッククラスがあります.2番目のパラメータは時間間隔で、デフォルトでは使用するクロックと同じ間隔です.内部にはdurationプライベートメンバーが維持され,定められたクロックによりepoch時点からの間隔が決定される.
コンストラクタ
デフォルトはポイント0で、durationオブジェクトを使用して構築されたものがリロードされます.また、レプリケーション構築テンプレート関数もあります.
constexpr time_point() : __d(duration::zero())
{ }
constexpr explicit time_point(const duration& __dur)
: __d(__dur)
{ }

// conversions
template<typename _Dur2>
constexpr time_point(const time_point<clock, _Dur2>& __t)
: __d(__t.time_since_epoch())
{ }

メンバー#メンバー#time_pointは、C APIとの時間的インタラクションの良好な定義を提供する.従って、time_tタイプと容易に付き合うことができ、epochからのdurationオブジェクトを返すための一意のメンバー関数time_since_epochが提供され、関連ctime関数を用いて処理することができる.
chrono::time_point<system_clock> tp = chrono::system_clock::now();
cout << tp.time_since_epoch().count() << endl;

//1452672734311762303
//system_clock ratio nano

えんざん
durationと似ていますtime_Pointはまた、静的メンバーminおよびmax、および算術演算操作も提供し、これらは内部メンテナンスされたdurationメンバーによって行われ、durationメンバーの様々な操作は前述したように保障され、time_pointtime_since_epochによってプライベートdurationメンバーのエントリ呼び出しを取得するだけでよい.また、durationと直接行う"+="および"-="の演算操作も提供され、通常の算術演算では、durationのオペランドタイプがある場合、time_pointのオペランド内部で維持されているdurationメンバー上で操作されると、戻りタイプはtime_pointである.両方がtime_pointタイプの場合、戻りタイプは両方のメンテナンスdurationメンバーの差であり、戻りタイプもdurationである.
chrono::seconds t(60);
chrono::time_point<chrono::system_clock> tp(t);
cout << tp.time_since_epoch().count() << endl;
tp += t;
cout << tp.time_since_epoch().count() << endl;
cout << (tp - t).time_since_epoch().count() << endl;//     time_point,        duration     count

chrono::time_point<chrono::system_clock> tp1(t);
cout << (tp - tp1).count() << endl; //     duration,    count

typedef chrono::duration<long, ratio<3600 * 24>> days;
chrono::time_point<chrono::system_clock> now = chrono::system_clock::now();
auto td = chrono::time_point_cast<days>(now);
cout << td.time_since_epoch().count() << " days" << endl;

出力:
60,000,000,000 120,000,000,000 60,000,000,000 60,000,000,000 16813 days
Clocks
現在のシステムクロックを表す3種類:-system_clock:システムから取得クロック-steady_clock:変更できないクロック-high_resolution_clock:高精度クロック、実際にはsystem_clockまたはsteady_clockの別名
gcc4.8バージョンのchronoファイルには、次のものが表示されます.
/** *  @brief Highest-resolution clock * * This is the clock "with the shortest tick period." Alias to * std::system_clock until higher-than-nanosecond definitions * become feasible. */
using high_resolution_clock = system_clock;
system_clockのデフォルトではnanosecondが最小単位として使用されます.次に、system_clockについて重点的に説明します.
定義#テイギ#
struct system_clock
{
  typedef chrono::nanoseconds                   duration;
  typedef duration::rep                     rep;
  typedef duration::period                  period;
  typedef chrono::time_point<system_clock, duration>    time_point;

  static_assert(system_clock::duration::min()
  < system_clock::duration::zero(),
  "a clock's minimum duration cannot be less than its epoch");

  static constexpr bool is_steady = false;

  static time_point
  now() noexcept;

  // Map to C API
  static std::time_t
  to_time_t(const time_point& __t) noexcept
  {
return std::time_t(duration_cast<chrono::seconds>
  (__t.time_since_epoch()).count());
  }

  static time_point
  from_time_t(std::time_t __t) noexcept
  {
typedef chrono::time_point<system_clock, seconds>   __from;
return time_point_cast<system_clock::duration>
    (__from(chrono::seconds(__t)));
  }
};

定義から,nanosecondsをdurationとして最小時間単位として内部的に維持する非常に簡単なクラスであることがわかる.3つのstatic関数のみが提供され、システム時点time_pointtime_tの相互変換を非常に容易に取得でき、ctimeインタラクションの保証を提供します.
auto tp = chrono::system_clock::now();
time_t nowt = chrono::system_clock::to_time_t(tp);
cout << nowt << endl;
cout << ctime(&nowt) << endl;
cout << put_time(localtime(&nowt), "%Y-%m-%d") << endl;

出力:
1452684162 Wed Jan 13 19:22:42 2016 2016-01-13
steady_についてclockも同様ですが、nowというstatic関数のみが提供され、time_tへの変換インタフェースはありません.他の特殊なニーズに対しては、独自のclockクラスを定義し、time_pointに最初のテンプレートパラメータとして渡して、カスタムの世界操作を行うことができる.