2017-11-18 105 views
1

我已經實施了一種計算開啓和關閉時間週期性行爲的方法,使用std::chrono::duration值和佔空比float給出的時間段。這顯示在下面的代碼塊中。持續時間和佔空比的值只在運行時提供,所以我認爲使用std :: ratio是不可能的。任何人都可以提出一個更清晰的方式來實現這個?從單個持續時間和比率計算兩個持續時間的正確方法

PeriodicPulse(const Period period, const float duty): mRunning(false) 
{ 
    if (duty < 0 || duty > 1) { 
     throw std::runtime_error("Duty value should be between 0-1."); 
    } 
    auto tempTime = std::chrono::duration<float, decltype(period)::period>(period.count() * duty); 
    mOnTime = std::chrono::duration_cast<decltype(mOnTime)>(tempTime); 
    tempTime = std::chrono::duration<float, decltype(period)::period>(period.count() * (1 - duty)); 
    mOffTime = std::chrono::duration_cast<decltype(mOffTime)>(tempTime); 
} 
+0

你的代碼不工作嗎?你打開和關閉的時間有什麼問題?也更好確保'duty> 0'。 – kabanus

+0

在功能上,沒有錯 - 至少在我到目前爲止的測試中。此代碼有效。我只是好奇,是否有一個'更好'的方法來做到這一點。謝謝,是的,我應該 - 太多啤酒! – tuskcode

+0

這是基於意見。就我個人而言,我認爲你的代碼是好的,「適當的」。如果你真的希望反饋更好地移動這個堆棧'codereview',這是更適合IMO。 – kabanus

回答

0

您的代碼看起來好像沒什麼問題,特別是如果你的測試顯示,它是做你想要什麼。下面我提供一些文體清理了,我已經把構造的PeriodicPulse範圍內:

struct PeriodicPulse 
{ 
    using Duration = std::chrono::milliseconds; 

    bool mRunning; 
    Duration mOnTime; 
    Duration mOffTime; 

    template <class Rep, class Period> 
    PeriodicPulse(const std::chrono::duration<Rep, Period> period, const float duty) 
     : mRunning(false) 
    { 
     if (duty < 0 || duty > 1) { 
      throw std::runtime_error("Duty value should be between 0-1."); 
     } 
     using namespace std::chrono; 
     duration<float, Period> tempTime = period * duty; 
     mOnTime = duration_cast<Duration>(tempTime); 
     tempTime = period * (1 - duty); 
     mOffTime = duration_cast<Duration>(tempTime); 
    } 
}; 
  • 我已經改名爲Periodstd::chrono::duration<Rep, Period>以表明它實際上是預計有型的持續時間,但用變量名period來描述持續時間的功能。這也有助於約束(我所假設的)是一個過於通用的模板參數。 (我的假設可能不正確)

  • 在功能範圍內,我發現重複使用std::chrono::過於冗長而難以閱讀。我更喜歡功能本地using namespace std::chrono;。你可能感覺不一樣。

  • 我取代:


auto tempTime = std::chrono::duration<float, decltype(period)::period>(period.count() * duty); 

與:

duration<float, Period> tempTime = period * duty; 

這重用來自改寫參數類型Period,並且避免.count()的不必要的使用米餘燼功能。

  • 因爲我已經創建了一個Duration別名,這樣我就不用說了decltype(mOnTime)mOnTimemOffTime分配。 decltype(mOnTime)沒有什麼不對,我發現Duration在這方面更具可讀性,我仍然可以在一個地方更改這些成員的類型。

  • duration_cast當爲tempTime賦予其第二個值時不需要,因爲存在隱式轉換爲基於浮點的持續時間。並且我再次避免了.count()成員函數,以便保持<chrono>類型系統的類型安全保護。

我測試了它這樣的:

#include "date/date.h" 
#include <chrono> 
#include <iostream> 

int 
main() 
{ 
    using date::operator<<; 
    using namespace std; 
    using namespace std::chrono; 
    using P = duration<int, ratio<1, 30>>; 
    PeriodicPulse p{P{3}, .2}; 
    cout << p.mOnTime << '\n'; 
    cout << p.mOffTime << '\n'; 
} 

,輸出:

20ms 
80ms 

這是相同的答案,我與你原來的代碼獲得。

使用"date/date.h"是沒有必要的。這只是我在偷懶p.mOnTimep.mOffTime