如何编写通用C++函数将任意chrono时长(含浮点单位)转为毫秒?
通用处理std::chrono时长转毫秒的函数实现
问题背景
初始定义了一个接收std::chrono::milliseconds的函数:
void foo(std::chrono::milliseconds ms) { std::cout << ms.count() << " milliseconds" << std::endl; }
调用整数字面量时长时可以正常工作:
int main() { using namespace std::chrono_literals; foo(3s); foo(1h); foo(100ms); }
输出:
3000 milliseconds 3600000 milliseconds 100 milliseconds
但传入浮点字面量时长(如3.5s、0.5s、0.3days)时会编译报错。
随后尝试的模板函数仅支持浮点秒,无法处理小时类的其他单位:
template<class T> void foo(std::chrono::duration<T> duration) { std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " milliseconds" << std::endl; }
解决方案
问题出在模板参数的写法上:std::chrono::duration<T>默认等价于std::chrono::duration<T, std::ratio<1>>(即秒单位),无法匹配hours、days等其他单位的duration类型。正确的做法是模板化duration的两个模板参数——数值类型(Rep)和时间比例(Period),这样就能接收任意类型的std::chrono::duration:
#include <chrono> #include <iostream> template<typename Rep, typename Period> void foo(std::chrono::duration<Rep, Period> duration) { // 转换为毫秒并输出 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration); std::cout << ms.count() << " milliseconds" << std::endl; } int main() { using namespace std::chrono_literals; // 测试各种时长 foo(1s); foo(1.5s); foo(1m); foo(1.5m); foo(1h); foo(3.5h); foo(0.3days); // 需要C++20及以上支持std::chrono::days }
说明
- 无需重载运算符:
std::chrono已经内置了不同单位duration之间的转换逻辑,duration_cast会自动处理比例换算,比如小时转毫秒时会自动乘以3600*1000。 - 浮点与整数时长兼容:模板参数
Rep可以是整数类型(如int)或浮点类型(如double),duration_cast会根据类型自动处理精度转换(浮点转整数时会截断小数部分,若需要四舍五入可以自行处理)。 - C++版本注意:
days字面量是C++20引入的特性,若使用更早版本,可自行定义std::chrono::duration<long long, std::ratio<86400>>作为天的单位。
内容的提问来源于stack exchange,提问作者Illusion
相关产品推荐
相关产品推荐

