2017-11-18 110 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