2017-11-18 8 views
1

std::chrono::duration値とデューティサイクルfloatによって与えられる期間を使用して、周期的な動作をオンとオフに計算する方法を実装しました。これは以下のコードブロックに示されています。期間とデューティサイクルの値は実行時にのみ供給されるので、std :: ratioの使用は問題外です。誰もこれを実装するためのよりクリーンな方法を提案することはできますか?単一の持続時間と比率から2つの継続時間を計算する正しい方法

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

あなたのテストでは、あなたが望むように動作していることが示されている場合は、コードがうまく見えます。

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); 
    } 
}; 
  • 私は実際にタイプの持続時間を有すると予想される示すためにstd::chrono::duration<Rep, Period>Periodに改名しましたが、私はいくつかの文体クリーンアップを提供し、私はPeriodicPulseのコンテキスト内でコンストラクタを入れているの下に変数名は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()の不必要な使用を避けますm ember機能。私はdecltype(mOnTime)を言わなければならないように、私はDurationエイリアスを作成しましたmOnTimemOffTimeの割り当てについては

  • decltype(mOnTime)に何も問題はありません。私はDurationをこの文脈では少し読みやすくしていますが、これらのメンバーのタイプを1か所で変更することはできます。

  • duration_cast浮動小数点ベースの期間への暗黙的な変換があるため、tempTimeに第2の値を指定する場合は不要です。そして、<chrono>タイプのシステムの型安全保護の中にとどまるように、私は再び.count()メンバ関数を避けました。

私はこのようにそれをテストした:

#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をストリーミングすることに怠惰であることです。

関連する問題