You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:36:01