【问题标题】:std::chrono::duration can be initialized by seconds, but not milliseconds?std::chrono::duration 可以以秒为单位初始化,但不能以毫秒为单位?
【发布时间】:2018-09-25 21:10:05
【问题描述】:

作品: std::chrono::duration<unsigned long long> test1 = std::chrono::seconds(1);

不起作用: std::chrono::duration<unsigned long long> test2 = std::chrono::milliseconds(1);

为什么不一样?持续时间内部没有足够的粒度吗?

从以毫秒为单位的值初始化持续时间的首选方法是什么?

【问题讨论】:

  • 您看到哪些错误与不起作用的错误?
  • 从一个以毫秒为单位的值初始化持续时间的首选方法是什么? auto. auto test2 = 1ms;
  • 如果我使用auto,我最终会得到std::chrono::milliseconds,显然需要将其转换为seconds 才能与chrono::duration 一起使用我认为duration 是无单位的?这会导致粒度问题吗?此外,为此需要duration_cast 也很丑。
  • 持续时间有点无单位,但它们有不同的类型和ratios。
  • 观看chrono 教程:youtube.com/watch?v=P32hvk8b13M,您可以在一小时内快速了解chrono

标签: c++ std chrono


【解决方案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.

【讨论】:

  • 你能描述一下截断吗? std::chrono::duration 是基于小得多的“滴答声”,对吧,所以它仍然代表 1 毫秒?
  • @VoidStar 不,它不会,因此需要显式转换。 duration 的刻度大小由传递给它的比率表示。 std::ratio&lt;1&gt; 的刻度大小表示每秒 1 个刻度。如果您需要比这更小的刻度(例如 std::chrono::milliseconds 或 std::chrono::nanoseconds 可用的刻度,您需要明确指定那些较小的刻度大小,例如 typedef std::duration&lt;unsigned long long, std::ratio&lt;1, 1'000'000'000&gt;&gt; my_duration 以获得与 std::chrono::nanoseconds 几乎相同的类型。
  • 嗯好吧,std::duration&lt;unsigned long long&gt; 并不像我想象的那样普遍/无单位。我认为默认设置是最小粒度,这样它可以更通用。我想这是关键概念,duration 根本不是无单位的,而是默认等于seconds。
  • @VoidStar 看看我对帖子所做的编辑。
猜你喜欢
  • 2023-02-07
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多