C++ <chrono>库是否支持使用运行时可变比率的duration类型?
C++
<chrono>运行时动态时长比率实现方案 原生<chrono>不支持运行时可变比率
std::duration的第二个模板参数要求是std::ratio类型,而std::ratio的分子、分母都必须是编译期常量,你示例中用运行时变量nTempo作为ratio模板参数的写法无法通过编译,原生标准库没有提供运行时可变比率的duration实现。
推荐实现方案
方案1:标准时间单位中转(无自定义扩展,最常用)
不需要自定义duration类型,直接以标准时间单位(比如秒)为中转做运行时换算即可,完全满足音乐类软件的BPM动态调整需求:
#include <chrono> using namespace std::chrono_literals; uint32_t nTempo {120}; while(running){ nTempo = ReadBPMEncoderValue(); // 单拍对应的标准时长:60秒除以当前BPM const auto per_beat = 60s / nTempo; // 计算45秒加4拍的总时长 const auto total_time = 45s + 4 * per_beat; // 如果需要转换为总节拍数,除以单拍时长即可 const double total_beats = total_time / per_beat; }
这个方案零额外开发成本,性能足够应对绝大多数场景,也能灵活适配BPM的实时调整。
方案2:自定义强类型运行时时长类(适合需要类型隔离的场景)
如果你想要类似原生duration的强类型约束,避免不同单位混用导致的逻辑bug,可以自己封装一套运行时比率的时长类型,内部存储计数值和运行时的比率参数,按需重载算术运算符即可:
#include <chrono> #include <cassert> using namespace std::chrono_literals; class BeatDuration { public: BeatDuration(int32_t beat_count, uint32_t bpm) : count_(beat_count), bpm_(bpm) {} // 支持隐式转换为标准chrono时长 operator std::chrono::duration<double>() const { return 60s * count_ / bpm_; } // 重载同类加法 BeatDuration operator+(const BeatDuration& other) const { assert(bpm_ == other.bpm_ && "不同BPM的节拍时长相加需要先做换算"); return BeatDuration(count_ + other.count_, bpm_); } // 按需实现其他运算符、换算逻辑即可 private: int32_t count_; uint32_t bpm_; };
如果对精度要求很高不想使用浮点运算,可以把内部存储改为分子分母整数形式,避免浮点误差。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

