如何在std::chrono中对时长做减法并保证结果非负?
C++ chrono 实现非负剩余时长的方案
问题场景与现有代码
你当前的代码用于计算下次执行的剩余延迟时间,但存在潜在问题:当已耗时duration超过目标延迟时长时,减法结果会是负数,不符合剩余时间的业务逻辑(剩余时间不能为负)。现有代码如下:
auto start = std::chrono::steady_clock::now(); ... auto duration = std::chrono::steady_clock::now() - start; return std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::milliseconds(getDelayBeforeNextExecution()) - duration);
解决方案:显式保证结果非负
必须显式与chrono::zero比较并返回零,因为C++的chrono::duration类型本身支持正负值(用来表示时间的先后方向),但在剩余延迟的场景下,负数没有实际意义,甚至可能导致后续等待逻辑出错。
你可以用两种方式实现:
方式一:条件判断
auto start = std::chrono::steady_clock::now(); ... auto duration = std::chrono::steady_clock::now() - start; // 先统一转换为目标毫秒类型,避免类型不匹配 auto target_delay = std::chrono::milliseconds(getDelayBeforeNextExecution()); auto remaining = target_delay - duration; // 确保剩余时间非负 if (remaining < std::chrono::milliseconds::zero()) { return std::chrono::milliseconds::zero(); } return std::chrono::duration_cast<std::chrono::milliseconds>(remaining);
方式二:使用std::max简化代码
利用std::max直接取计算结果和零的较大值,代码更简洁:
auto start = std::chrono::steady_clock::now(); ... auto duration = std::chrono::steady_clock::now() - start; auto target_delay = std::chrono::milliseconds(getDelayBeforeNextExecution()); return std::max( std::chrono::milliseconds::zero(), std::chrono::duration_cast<std::chrono::milliseconds>(target_delay - duration) );
为什么要这么做?
当已耗时超过目标延迟时,剩余逻辑应该立即执行(即延迟0毫秒),而不是返回负数。如果直接返回负数,传给std::this_thread::sleep_for这类等待函数时,会触发未定义行为,导致程序异常或逻辑错误。
内容的提问来源于stack exchange,提问作者gruszczy
相关产品推荐
相关产品推荐

