c++ - std::chrono::duration 可以以秒为单位初始化,但不能以毫秒为单位?
问题描述
作品:
std::chrono::duration<unsigned long long> test1 = std::chrono::seconds(1);
不起作用:
std::chrono::duration<unsigned long long> test2 = std::chrono::milliseconds(1);
为什么有区别?持续时间在内部是否没有足够的粒度?
从以毫秒为单位的值初始化持续时间的首选方法是什么?
解决方案
std::chrono::duration
的模板参数列表有两个参数:保存基础数据的类型,以及std::ratio
表示持续时间指数的参数。类似std::chrono::seconds
和std::chrono::milliseconds
的类型是该模板的特化,分别使用std::chrono::duration<int64_t, std::ratio<1>>
和std::chrono::duration<int64_t, std::ratio<1, 1000>>
。
如果您不std::ratio
为该类型提供参数,它将默认为std::ratio<1>
.
结果,您的自定义持续时间类型隐式采用了形式std::chrono::duration<unsigned long long, std::ratio<1>>
,这使得它几乎等同于std::chrono::seconds
(唯一的区别是无符号值而不是有符号值),但是因为它的比率高于提供给std::chrono::milliseconds
类模板的比率禁止赋值/原始转换。对于这种情况,如果您希望分配通过,您需要显式转换它:
typedef std::duration<unsigned long long> my_duration;
//my_duration test1 = std::chrono::milliseconds(1);//Forbidden
my_duration test1 = std::chrono::duration_cast<my_duration>(std::chrono::milliseconds(1)); //Permitted, will be truncated
my_duration test2 = std::chrono::duration_cast<my_duration>(1ms); //Permitted, may be easier to read
该std::ratio
参数表示持续时间的刻度大小。刻度尺寸越小,代表持续时间的基础数字就越大。举个例子:
using seconds = std::chrono::seconds; //std::duration<int64_t, std::ratio<1,1>>
using milliseconds = std::chrono::milliseconds; //std::duration<int64_t, std::ratio<1,1000>>
using nanoseconds = std::chrono::nanoseconds; //std::duration<int64_t, std::ratio<1,1000000000>>
seconds time1 = 5s; //underlying integer value is 5.
milliseconds time2 = 5ms; //underlying integer value is 5.
time2 = time1; //underlying integer value for time2 is 5000, for time1 is still 5.
time2 = 17ms; //underlying integer value is 17.
//time1 = time2; //forbidden; tick size of time2 is smaller than time1
time1 = std::chrono::duration_cast<seconds>(time2);
//underlying integer value for time1 is 0, due to truncation; time2 is still 17.
nanoseconds time3 = 5ms; //underlying integer value is 5000000.
time1 = 2s; //underlying integer value is 2.
time3 = time1; //underlying integer value is 2000000000.
推荐阅读
- r - 在 ggplot 中按形状添加图例(在后面添加第二个问题:计算数字导数)
- c# - 如何通过接口方法使用 CallerMemberName
- r - 为什么我在合并函数中有一些重复的行?
- doctrine-orm - TYPO3:如何为 Doctrine insert() 迁移 $GLOBALS['TYPO3_DB']->quoteStr()
- flutter - Flutter:如何配置 Facebook 进行身份验证
- c++ - 内存堆和泄漏总结
- html - 在Angular 8中使用管道将不安全的URL转换为安全的问题
- php - 使用 laravel 框架在 000webhost 中上传图像不起作用
- scala - Scala Breeze Beta分布参数估计
- excel - 根据另一张工作表中的行数向下复制行