2016-03-04 24 views
-1

有人请描述下面的代码吗?C++ 11 chrono conditinal statements

由于

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)) { } 

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()) { } 
+0

我们已经不知道你这个问题,想要什么。代码有问题吗? –

+0

究竟是什么让我们解释这段代码?没有人有时间对此进行全面分析。 – jotik

回答

3

这些是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)) 
    { } 

格式化有助于可读性。只要它有一些风格,风格并不重要。 ;-)

该第一构造函数是constexprexplicit,如果输入是编译时间常数,所构建的持续时间可以是一个编译时间常数,并且输入将不隐含转换为持续时间的意思。

此构造函数的总体目的是明确地将标量(或标量的仿真)转换为chrono::duration

模板参数列表中的第二个typename是对_Rep2的约束。它说:

  1. _Rep2必须隐式转换为reprepduration的表示类型)和

  2. 要么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构造。也就是说,它将一个单位转换成另一个单位(例如,hoursminutes)。

同样,对模板参数Rep2Period2有约束。如果这些限制不符合,构造函数不存在。约束条件是:

  1. rep是浮点,或

  2. _Period2/period导致ratio为1和_Rep2分母是整体型(或仿真物)。

这种约束的效果是,如果你有一个浮点时间,然后任何其他时间(整数或浮点数为主)将隐式转换到它。

但是积分持续时间更挑剔。如果要转换为基于积分的持续时间,则源时间段不能为为基于浮点数的点,则从基于源积分的持续时间转换为目标基于积分的持续时间必须精确为。也就是说,转换不能除1以外的任何数字(只有乘法)。

例如:

hours h = 30min; // will not compile 
minutes m = 1h; // ok 

第一个例子不编译因为它需要除以60,产生h这是不等于30min。但第二个例子编译,因为m将完全等于1h(它将保存60min)。

你可以从这个拿走的:

  1. 始终<chrono>为你做转换。如果您在代码中乘以或除以60或1000(或其他),则不必要地引入错误的可能性。此外,如果您将所有转化委托给<chrono>,则<chrono>会通知您是否有任何有损转换。

  2. 尽可能使用隐式<chrono>转换。他们要么编译,要么确切,要么他们不会编译。如果他们不编译,这意味着您要求进行包含截断错误的转换。只要你不这样做,就可以要求截断错误。要求提截断转换的语法是:

    hours h = duration_cast<hours>(30min); // ok, h == 0h 
    
+0

非常感谢。很好的解释。 – xpath