我已经实现了一种方法来计算周期性行为的开启和关闭时间,使用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 :(得分: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);
}
};
我已将Period
重命名为std::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()
成员函数。
对于mOnTime
和mOffTime
的分配,我创建了Duration
别名,因此我不必说decltype(mOnTime)
。 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.mOnTime
和p.mOffTime
时很懒惰。