这些是GCC /的libstdC++实现了std::chrono::duration
构造的。我们可以一次看一个:
template <typename _Rep2,
typename = typename enable_if
<
is_convertible<_Rep2, rep>::value &&
(treat_as_floating_point<rep>::value ||
!treat_as_floating_point<_Rep2>::value)
>::type>
constexpr
explicit
duration(const _Rep2& __rep)
: __r(static_cast<rep>(__rep))
{ }
格式化有助于可读性。只要它有一些风格,风格并不重要。 ;-)
该第一构造函数是constexpr
和explicit
,如果输入是编译时间常数,所构建的持续时间可以是一个编译时间常数,并且输入将不隐含转换为持续时间的意思。
此构造函数的总体目的是明确地将标量(或标量的仿真)转换为chrono::duration
。
模板参数列表中的第二个typename
是对_Rep2
的约束。它说:
_Rep2
必须隐式转换为rep
(rep
是duration
的表示类型)和
要么rep
是一个浮点型(或模拟一个浮点型),或_Rep2
不是浮点类型(或模拟一个)。
如果不满足这些约束条件,则此构造函数实际上不存在。这些约束的效果是,您可以从浮点型和整型参数构造基于浮点的浮点型duration
,但必须使用整型参数构造基于整型的浮点型duration
。
该约束的基本原理是防止默默丢弃浮点参数的小数部分。例如:
minutes m{1.5}; // compile-time error
这不会编译,因为minutes
是不可或缺的基础,而参数是浮点的,如果它没有编译,将丢弃该.5
导致1min
。
现在对于第二chrono::duration
构造:
template <typename _Rep2,
typename _Period2,
typename = typename enable_if
<
treat_as_floating_point<rep>::value ||
(ratio_divide<_Period2, period>::den == 1 &&
!treat_as_floating_point<_Rep2>::value)
>::type>
constexpr
duration(const duration<_Rep2, _Period2>& __d)
: __r(duration_cast<duration>(__d).count())
{ }
此构造用作转换chrono::duration
构造。也就是说,它将一个单位转换成另一个单位(例如,hours
到minutes
)。
同样,对模板参数Rep2
和Period2
有约束。如果这些限制不符合,构造函数不存在。约束条件是:
rep
是浮点,或
_Period2/period
导致ratio
为1和_Rep2
分母是整体型(或仿真物)。
这种约束的效果是,如果你有一个浮点时间,然后任何其他时间(整数或浮点数为主)将隐式转换到它。
但是积分持续时间更挑剔。如果要转换为基于积分的持续时间,则源时间段不能为为基于浮点数的点和,则从基于源积分的持续时间转换为目标基于积分的持续时间必须精确为。也就是说,转换不能除1以外的任何数字(只有乘法)。
例如:
hours h = 30min; // will not compile
minutes m = 1h; // ok
第一个例子不编译因为它需要除以60,产生h
这是不等于30min
。但第二个例子编译,因为m
将完全等于1h
(它将保存60min
)。
你可以从这个拿走的:
始终让<chrono>
为你做转换。如果您在代码中乘以或除以60或1000(或其他),则不必要地引入错误的可能性。此外,如果您将所有转化委托给<chrono>
,则<chrono>
会通知您是否有任何有损转换。
尽可能使用隐式<chrono>
转换。他们要么编译,要么确切,要么他们不会编译。如果他们不编译,这意味着您要求进行包含截断错误的转换。只要你不这样做,就可以要求截断错误。要求提截断转换的语法是:
hours h = duration_cast<hours>(30min); // ok, h == 0h
我们已经不知道你这个问题,想要什么。代码有问题吗? –
究竟是什么让我们解释这段代码?没有人有时间对此进行全面分析。 – jotik