【问题标题】:Does <chrono> allow durations with a runtime variable ratio?<chrono> 是否允许具有运行时可变比率的持续时间?
【发布时间】:2021-10-07 21:01:43
【问题描述】:

我刚刚在&lt;chrono&gt; 上观看了Howard Hinnant's talk,似乎虽然您可以创建自定义durations,但它们在编译时需要一个固定的比率。他举的例子是:

using frames = duration<int32_t,ratio<1,60>>;

这会创建一个名为framesduration,其比率为 1 到 60。(换句话说,视频帧速率为每秒 60 帧)。

但是,如果我想创建一个具有可在运行时更改的可变比率的 duration,该怎么办?

假设我想制作具有用户可配置每分钟节拍的音乐软件。我想做这样的事情:

uint32_t nTempo {120};

using beats = duration<int32_t,ratio<1,nTempo>>;

while(running){
   // The user is turning an encoder that changes the ratio between beats and minutes.
   nTempo = ReadBPMEncoderValue();
   // Calculate the number of beats in 45 seconds plus 4 beats,
   // based on the current tempo:
   beats x = 45s + beats{4};
}

有没有办法从&lt;chrono&gt; 获得这个功能?我需要编写自定义扩展吗?还是有更好的方法?

【问题讨论】:

  • 简答:不。模板参数必须在编译时知道。

标签: c++ chrono


【解决方案1】:

durationratio 旨在解决的问题特定于编译时概念。具体来说,如果您有一个以秒为单位的函数,您如何防止人们以纳秒为单位调用它?或者更好的是,您如何使该调用自动执行正确的操作?

API 通常只是一个整数,调用者只需提供一个整数。双方都必须记住该整数的含义,并且永远不要弄错。

durationratio 通过在类型本身中编码时间单位来解决这个问题。如果您的函数需要以秒为单位的时间,则需要 duration&lt;integer_type, seconds&gt;。它就在那里,明确地写出来让每个人都可以看到。此外,裸整数不能隐式转换为duration;如果您想转换它,用户必须指定该持续时间的单位。这迫使他们思考这次的实际意义。

最后,duration 可以隐式地从一个单位转换为另一个单位,前提是这种转换不会丢失精度。所以如果一个 API 需要纳秒,我可以通过一秒的时间就好了。

所有这些都是编译时问题和解决方案。 ratio 不适用于运行时转换。所以你需要创建一个类型来做你想做的事情。而且它无法完成 ratio 所做的编译时操作。

【讨论】:

  • 使用运行时可变持续时间数据类型扩展&lt;chrono&gt; 是否是一个好的实践解决方案,例如从duration 派生的dynamic_duration?还是应该使用不同的std 库?我在想一个解决方案可能是创建一个beats struct 派生自seconds duration (并且秒持续时间),但有一个SetBPM()方法来改变比率,并有重载的操作符自动将任何值转换为secondsduration,使其与&lt;chrono&gt;兼容。 1/2
  • 或者由于&lt;chrono&gt; 的结构方式,任何类型的运行时单元转换都是不可能的? 2/2
  • @Nick:您不能向现有标头添加类型,也不能向命名空间std 添加任何内容(模板特化除外)。你不应该想要。如果您有一些运行时需求,请为此编写一个库。
猜你喜欢
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多