這些是GCC /的libstdC++實現了std::chrono::duration
構造的。我們可以一次看一個:
template <typename _Rep2,
typename = typename enable_if
<
is_convertible<_Rep2, rep>::value &&
(treat_as_floating_point<rep>::value ||
!treat_as_floating_point<_Rep2>::value)
>::type>
constexpr
explicit
duration(const _Rep2& __rep)
: __r(static_cast<rep>(__rep))
{ }
格式化有助於可讀性。只要它有一些風格,風格並不重要。 ;-)
該第一構造函數是constexpr
和explicit
,如果輸入是編譯時間常數,所構建的持續時間可以是一個編譯時間常數,並且輸入將不隱含轉換爲持續時間的意思。
此構造函數的總體目的是明確地將標量(或標量的仿真)轉換爲chrono::duration
。
模板參數列表中的第二個typename
是對_Rep2
的約束。它說:
_Rep2
必須隱式轉換爲rep
(rep
是duration
的表示類型)和
要麼rep
是一個浮點型(或模擬一個浮點型),或_Rep2
不是浮點類型(或模擬一個)。
如果不滿足這些約束條件,則此構造函數實際上不存在。這些約束的效果是,您可以從浮點型和整型參數構造基於浮點的浮點型duration
,但必須使用整型參數構造基於整型的浮點型duration
。
該約束的基本原理是防止默默丟棄浮點參數的小數部分。例如:
minutes m{1.5}; // compile-time error
這不會編譯,因爲minutes
是不可或缺的基礎,而參數是浮點的,如果它沒有編譯,將丟棄該.5
導致1min
。
現在對於第二chrono::duration
構造:
template <typename _Rep2,
typename _Period2,
typename = typename enable_if
<
treat_as_floating_point<rep>::value ||
(ratio_divide<_Period2, period>::den == 1 &&
!treat_as_floating_point<_Rep2>::value)
>::type>
constexpr
duration(const duration<_Rep2, _Period2>& __d)
: __r(duration_cast<duration>(__d).count())
{ }
此構造用作轉換chrono::duration
構造。也就是說,它將一個單位轉換成另一個單位(例如,hours
到minutes
)。
同樣,對模板參數Rep2
和Period2
有約束。如果這些限制不符合,構造函數不存在。約束條件是:
rep
是浮點,或
_Period2/period
導致ratio
爲1和_Rep2
分母是整體型(或仿真物)。
這種約束的效果是,如果你有一個浮點時間,然後任何其他時間(整數或浮點數爲主)將隱式轉換到它。
但是積分持續時間更挑剔。如果要轉換爲基於積分的持續時間,則源時間段不能爲爲基於浮點數的點和,則從基於源積分的持續時間轉換爲目標基於積分的持續時間必須精確爲。也就是說,轉換不能除1以外的任何數字(只有乘法)。
例如:
hours h = 30min; // will not compile
minutes m = 1h; // ok
第一個例子不編譯因爲它需要除以60,產生h
這是不等於30min
。但第二個例子編譯,因爲m
將完全等於1h
(它將保存60min
)。
你可以從這個拿走的:
始終讓<chrono>
爲你做轉換。如果您在代碼中乘以或除以60或1000(或其他),則不必要地引入錯誤的可能性。此外,如果您將所有轉化委託給<chrono>
,則<chrono>
會通知您是否有任何有損轉換。
儘可能使用隱式<chrono>
轉換。他們要麼編譯,要麼確切,要麼他們不會編譯。如果他們不編譯,這意味着您要求進行包含截斷錯誤的轉換。只要你不這樣做,就可以要求截斷錯誤。要求提截斷轉換的語法是:
hours h = duration_cast<hours>(30min); // ok, h == 0h
我們已經不知道你這個問題,想要什麼。代碼有問題嗎? –
究竟是什麼讓我們解釋這段代碼?沒有人有時間對此進行全面分析。 – jotik