Hello World Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #include <chrono> #include <ratio> #include <iostream> #include <iomanip> template <typename T> class TD; template <typename _Value, typename _Fraction> std::ostream& operator << (std::ostream& os, const std::chrono::duration<_Value, _Fraction>& dur) { os << "[" << dur.count() << " of " << _Fraction::num << "/" << _Fraction::den << " sec]"; return os; } int main() { /* Basic Representation */ std::chrono::duration<int> twentySec(20); // value: 20, fraction: 1 sec (default) std::chrono::duration<double, std::ratio<60>> halfMin(0.5); // value: 0.5, fraction: 60 sec std::chrono::duration<long, std::milli> oneMs(1); // value: 1, fraction: 1 milli sec /* Use Helper Class */ std::chrono::seconds twentySec2(20); std::chrono::hours oneDay(24); std::chrono::microseconds oneMs2(1); //std::chrono::minutes halfMin2(0.5);// compile error, the duration type is int /* Arithmetic */ std::chrono::seconds d1(42); std::chrono::milliseconds d2(10); auto diff = d1 - d2; std::cout << diff.count() << std::endl; // 41990 (of 1/1000 sec) std::chrono::duration<int, std::ratio<1, 3>> d3(1); std::chrono::duration<int, std::ratio<1, 5>> d4(1); auto add = d3 + d4; std::cout << add.count() << std::endl; // 8 (of 1/15 sec) std::cout << std::boolalpha << (d3 < d4) << std::endl;// false /* Arithmetic Return Type */ //TD<decltype(diff)> x;// compiler deduce: TD<std::chrono::duration<__int64,std::milli>> //TD<decltype(add)> x;// compiler deduce: TD<std::chrono::duration<int,std::ratio<0x01,0x0f>>> //TD<decltype(twentySec2 - oneDay)> x;// compiler deduce: TD<std::chrono::duration<__int64,std::ratio<0x01,0x01>>> //TD<decltype(twentySec2 - oneMs2)> x;// compiler deduce: TD<std::chrono::duration<__int64,std::micro>> /* Arithmetic and Conversion */ std::chrono::milliseconds ms(0); // undefined value without (0) ms += twentySec2 + oneDay; --ms; ms *= 2; std::cout << ms.count() << " ms" << std::endl;//172839998 ms std::chrono::nanoseconds ns(ms); std::cout << ns.count() << " ns" << std::endl;// 172839998000000 ns /* Static Operations */ auto zeroMS = std::chrono::milliseconds::zero();// duration with zero value auto maxMS = std::chrono::milliseconds::max();// duration with max value auto minMS = std::chrono::milliseconds::min();// duration with min value using TypeMsValue = std::chrono::milliseconds::rep; using TypeMsFraction = std::chrono::milliseconds::period; std::cout << twentySec << std::endl; // use overloaded operator << std::cout << d3 << std::endl; // use overloaded operator << /* Explicit Conversion */ // example 1: convert to different fraction std::chrono::seconds sec(55); //std::chrono::minutes m1 = sec; // compile-time error std::chrono::minutes m1 = std::chrono::duration_cast<std::chrono::minutes>(sec); std::cout << m1 << std::endl; // value 0 due to information lost // example 2: conver to different value type, double to long long halfMin;// type: std::chrono::duration<double, std::ratio<60>> //std::chrono::seconds s1 = halfMin; // compile-time error std::chrono::seconds s1 = std::chrono::duration_cast<std::chrono::seconds>(halfMin); std::cout << s1 << std::endl; // [30 of 1/1 sec] // example 3: segment into different units ms = std::chrono::milliseconds(7255042); std::chrono::hours hh = std::chrono::duration_cast<std::chrono::hours>(ms); std::chrono::minutes mm = std::chrono::duration_cast<std::chrono::minutes>(ms % std::chrono::hours(1)); std::chrono::seconds ss = std::chrono::duration_cast<std::chrono::seconds>(ms % std::chrono::minutes(1)); std::chrono::milliseconds msec = std::chrono::duration_cast<std::chrono::milliseconds>(ms % std::chrono::seconds(1)); std::cout << "raw: " << hh << "::" << mm << "::" << ss << "::" << msec << std::endl; std::cout << " " << std::setfill('0') << std::setw(2) << hh.count() << "::" << std::setw(2) << mm.count() << "::" << std::setw(2) << ss.count() << "::" << std::setw(2) << msec.count() << std::endl; } |
chrono
chrono library 是一個可以提供時間與日期且精準度中性的 C++11 函式庫主要成分:
- duration: 在一個時間單位下的數量。例如,3 個 分鐘(minute) 表示 3 分鐘、3 個 0.5秒(0.5 seconds) 表示 1.5 秒
- timepoint: 一個起始時間(epoch) 與一個 duration 的組合。例如,千禧年午夜,可表示成 自從 1970 年 1 月 1 日起 1262300400 秒
- clock: 用來定義 epoch,不同的 clock 有不同的 epoch
Duration
- 為 value 與 fraction 的組合,其中:
- value
- 表示次數
- duration 的第一個 template argument 為此次數的型別
- fraction
- 表示以秒為基準的單位
- 常用 ratio 來表示
- 常用的 helper type 可參考此 Link
- 注意:value 的 type 僅支援 signed integer
- 若使用 default ctor 建構 duration,(即不傳入任何參數),其值是 undefined
Duration 的運算
- 兩個 duration 運算後,以秒為基準的單位可能會改變,即 fraction 部分可能會不同
- 回傳型別是 common_type 的 SPECIALIZATIONS,為一個 duraiton,其中:
- value 定義為兩個 duration value 的 common_type
- fraction 定義為 ratio<兩者最大公因數, 兩者最小公倍數>
- 不同 Duration 間轉換
- implicit type conversion
- 一個 duration 也可透過 ctor 或 assignment 轉成另一個單位的 duration,只要有支援 implicit type conversion (僅限於大單位轉小單位,即變得更精準的情況)
- duration_cast
- 若要從小單位轉大單位,即有機會造成資訊流失情況下,需要用 duration_cast,例如 42010 ms 轉成 42 s
Note:
使用 Visual Studio 2013 測試上面的 code,發現 84 到 86 行不 work,應該是 VS 的 lib 實作有問題,回傳型別方面的問題,這邊就不深入研究此錯誤了。另一方面,使用 g++ 就完全正常。
Reference:
- The C++ Standard Library: A Tutorial and Reference, Second Edition
- Visual Studio 2013
沒有留言:
張貼留言