2016-03-04 70 views
-1

有人請描述下面的代碼嗎?C++ 11 chrono conditinal statements

由於

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)) { } 

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()) { } 
+0

我們已經不知道你這個問題,想要什麼。代碼有問題嗎? –

+0

究竟是什麼讓我們解釋這段代碼?沒有人有時間對此進行全面分析。 – jotik

回答

3

這些是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)) 
    { } 

格式化有助於可讀性。只要它有一些風格,風格並不重要。 ;-)

該第一構造函數是constexprexplicit,如果輸入是編譯時間常數,所構建的持續時間可以是一個編譯時間常數,並且輸入將不隱含轉換爲持續時間的意思。

此構造函數的總體目的是明確地將標量(或標量的仿真)轉換爲chrono::duration

模板參數列表中的第二個typename是對_Rep2的約束。它說:

  1. _Rep2必須隱式轉換爲reprepduration的表示類型)和

  2. 要麼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構造。也就是說,它將一個單位轉換成另一個單位(例如,hoursminutes)。

同樣,對模板參數Rep2Period2有約束。如果這些限制不符合,構造函數不存在。約束條件是:

  1. rep是浮點,或

  2. _Period2/period導致ratio爲1和_Rep2分母是整體型(或仿真物)。

這種約束的效果是,如果你有一個浮點時間,然後任何其他時間(整數或浮點數爲主)將隱式轉換到它。

但是積分持續時間更挑剔。如果要轉換爲基於積分的持續時間,則源時間段不能爲爲基於浮點數的點,則從基於源積分的持續時間轉換爲目標基於積分的持續時間必須精確爲。也就是說,轉換不能除1以外的任何數字(只有乘法)。

例如:

hours h = 30min; // will not compile 
minutes m = 1h; // ok 

第一個例子不編譯因爲它需要除以60,產生h這是不等於30min。但第二個例子編譯,因爲m將完全等於1h(它將保存60min)。

你可以從這個拿走的:

  1. 始終<chrono>爲你做轉換。如果您在代碼中乘以或除以60或1000(或其他),則不必要地引入錯誤的可能性。此外,如果您將所有轉化委託給<chrono>,則<chrono>會通知您是否有任何有損轉換。

  2. 儘可能使用隱式<chrono>轉換。他們要麼編譯,要麼確切,要麼他們不會編譯。如果他們不編譯,這意味着您要求進行包含截斷錯誤的轉換。只要你不這樣做,就可以要求截斷錯誤。要求提截斷轉換的語法是:

    hours h = duration_cast<hours>(30min); // ok, h == 0h 
    
+0

非常感謝。很好的解釋。 – xpath