原 总结 C++11 chrono duration ratio 

概览

c++新标准提供了新的线程库,最近在写测试代码的时候需要让当前线程休眠,之前直接调用windows提供的Sleep()就好了,新标准中可以使用std::this_thread::sleep_for()或者std::this_thread::sleep_until()

来实现休眠。其中涉及到了std::chrono::durationstd::chrono::time_point。本篇只总结std::chrono::durationstd::chrono::time_point会再写一篇总结。

std::chrono::duration

描述

std::chrono::duration定义在文件中,用来表示一个时间段。

cppreference上的原话如下:

Class template std::chrono::duration represents a time interval.

It consists of a count of ticks of type Rep and a tick period, where the tick period is a compile-time rational constant representing the number of seconds from one tick to the next.

The only data stored in a duration is a tick count of type Rep. If Rep is floating point, then the duration can represent fractions of ticks. Period is included as part of the duration's type, and is only used when converting between different durations.

Rep参数代表了可以传入的时间单位的类型,可以为float, int, int64等等,如果为float表示可以传入时间单位的一部分,比如传入1.2表示1.2倍个时间单位

Period参数代表了时间单位,可以为微秒,毫秒,秒,分钟,小时等(或者其它自定义的单位,类型为std::ratio)。

注:

  1. 上文中的tick可以理解为周期,或时间单位。
  2. the number of seconds 表示是周期值基于秒来计算的。

类定义

std::chrono::duration是一个模板类,关键代码摘录如下(格式有调整):

  1. template<class _Rep, class _Period> 

  2. class duration { 

  3. public: 

  4. typedef duration<_Rep, _Period> _Myt; 

  5. typedef _Rep rep; 

  6. typedef _Period period; 


  7. // constructor, save param to _MyRep, used by count() member function. 

  8. template<class _Rep2, 

  9. class = typename enable_if<is_convertible<_Rep2, _Rep>::value 

  10. && (treat_as_floating_point<_Rep>::value || !treat_as_floating_point<_Rep2>::value), 

  11. void>::type> 

  12. constexpr explicit duration(const _Rep2& _Val) 

  13. : _MyRep(static_cast<_Rep>(_Val)) 






  14. constexpr _Rep count() const { return (_MyRep); } 

  15. }; 


  16. // convert duration from one unit to another. 

  17. template<class _To, class _Rep, class _Period> inline 

  18. constexpr typename enable_if<_Is_duration<_To>::value, _To>::type 

  19. duration_cast(const duration<_Rep, _Period>& _Dur) 



  20. typedef ratio_divide<_Period, typename _To::period> _CF; 


  21. typedef typename _To::rep _ToRep; 

  22. typedef typename common_type<_ToRep, _Rep, intmax_t>::type _CR; 


  23. #pragma warning(push) 

  24. #pragma warning(disable: 6326) // Potential comparison of a constant with another constant. 

  25. return (_CF::num == 1 && _CF::den == 1 

  26. ? static_cast<_To>(static_cast<_ToRep>(_Dur.count())) 

  27. : _CF::num != 1 && _CF::den == 1 

  28. ? static_cast<_To>(static_cast<_ToRep>( 

  29. static_cast<_CR>( 

  30. _Dur.count()) * static_cast<_CR>(_CF::num))) 

  31. : _CF::num == 1 && _CF::den != 1 

  32. ? static_cast<_To>(static_cast<_ToRep>( 

  33. static_cast<_CR>(_Dur.count()) 

  34. / static_cast<_CR>(_CF::den))) 

  35. : static_cast<_To>(static_cast<_ToRep>( 

  36. static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num) 

  37. / static_cast<_CR>(_CF::den)))); 

  38. #pragma warning(pop) 



duration_cast()分析

函数duration_cast()提供了在不同的时间单位之间进行转换的功能。

duration_cast()主要分为两部分:

  • 通过ratio_divide定义了从一个ratio转换到另外一个ratio的转换比例。

    比如1/102/5的转换比例是1/4 ((1/10/(2/5)) = 1/4),也就是说一个1/10相当于1/42/5

    对应到代码里就是_CF::num = 1, _CF::den = 4.

  • 根据转换比例把n个单位的原数据转换到目标数据(return语句)

    return语句写的这么复杂是为了效率,避免不必要的乘除法,当分子是1的时候没必要乘,当分母是1的时候没必要除。

    简化一下(去掉了强制类型转换)就是:

    return _Dur.count() * (_CF::num / _CF::den);

通俗点讲:如果AB的转换比例是num/den,那么1A可以转换为num/denB, nA可以转换为 n * (num/den)B

注:vs自带的源码真心不易读,推荐参考boost源码。

预定义的duration

vs为了写代码方便,预定义了几个常用的时间单位,摘录如下:

  1. typedef duration<long long, nano> nanoseconds; // 纳秒 

  2. typedef duration<long long, micro> microseconds; // 微秒 

  3. typedef duration<long long, milli> milliseconds; // 毫秒 

  4. typedef duration<long long> seconds; // 秒 

  5. typedef duration<int, ratio<60> > minutes; // 分钟 

  6. typedef duration<int, ratio<3600> > hours; // 小时 

根据以上定义我们可以发现std::chrono::microseconds定义中的Rep的类型是long longPeriod类型是milli

注:因为std::chrono::microseconds定义中的Rep的类型是long long, 我们不能通过如下方法来休眠100.5毫秒std::this_thread::sleep_for(std::chrono::microseconds(100.5));,类型不匹配,会报编译错误。如果想休眠100.5毫秒,我们可以这么写:

std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(100.5f));

示例代码

例1:分钟转换为毫秒

  1. #include <iostream> 

  2. #include <chrono> 

  3. int main() 



  4. std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::minutes(3)); 

  5. std::cout << "3 minutes equals to " << ms.count() << " milliseconds\n"; 

  6. std::cin.get(); 



例2. 自定义单位转换

  1. #include <iostream> 

  2. #include <chrono> 


  3. typedef std::chrono::duration<float, std::ratio<3, 1> > three_seconds; 

  4. typedef std::chrono::duration<float, std::ratio<1, 10> > one_tenth_seconds; 


  5. int main() 



  6. three_seconds s = std::chrono::duration_cast<three_seconds>(one_tenth_seconds(3)); 

  7. std::cout << "3 [1/10 seconds] equal to " << s.count() << " [3 seconds]\n"; 

  8. std::cin.get(); 



例3. 休眠100毫秒

  1. #include <thread> 

  2. #include <chrono> 

  3. int main() 



  4. std::this_thread::sleep_for(std::chrono::milliseconds(100)); 

  5. // or 

  6. std::this_thread::sleep_for(std::chrono::duration<long long, std::milli>(100)); 

  7. // or  

  8. // typedef ratio<1, 1000> milli; 

  9. std::this_thread::sleep_for(std::chrono::duration<long long, std::ratio<1, 1000> >(100)); 



参考资料

[原]C++新标准之std::chrono::duration的更多相关文章

  1. [原]C++新标准之std::chrono::time_point

    原 总结 STL 标准库 chrono time_point ratio  概览 类定义 总结 思考 拓展 system_clock steady_clock high_resolution_cloc ...

  2. [原]C++新标准之std::ratio

    原 总结 ratio  概览 类定义 预定义ratio 应用 示例代码 参考资料 概览 std::ratio定义在<ratio>文件中,提供了编译期的比例计算功能.为std::chrono ...

  3. [原]C++新标准之std::thread

    原 总结 C++11 thread  概览 std::thread 类定义 各个成员函数的简单介绍 例子 更多 参考资料 概览 从C++11开始提供了线程的支持,终于可以方便的编写跨平台的线程代码了. ...

  4. C++11 std::chrono库详解

    所谓的详解只不过是参考www.cplusplus.com的说明整理了一下,因为没发现别人有详细讲解. chrono是一个time library, 源于boost,现在已经是C++标准.话说今年似乎又 ...

  5. c++11 时间类 std::chrono

    概念: chrono库:主要包含了三种类型:时间间隔Duration.时钟Clocks和时间点Time point. Duration:表示一段时间间隔,用来记录时间长度,可以表示几秒钟.几分钟或者几 ...

  6. std::chrono计算程序运行时间

    void CalRunTime() { auto t1=std::chrono::steady_clock::now(); //run code auto t2=std::chrono::steady ...

  7. C++11新特性,利用std::chrono精简传统获取系统时间的方法

    一.传统的获取系统时间的方法 传统的C++获取时间的方法须要分平台来定义. 相信百度代码也不少. 我自己写了下,例如以下. const std::string getCurrentSystemTime ...

  8. C++ 11新特性:std::future & std::shared_future) (转载)

    上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...

  9. c++11 标准库函数 std::move 和 完美转发 std::forward

    c++11 标准库函数 std::move 和 完美转发 std::forward #define _CRT_SECURE_NO_WARNINGS #include <iostream> ...

随机推荐

  1. Vulkan SDK之 CommandBuff

    Basic Command Buffer Operation 调用指定的api, 驱动将命令放入指定的buff当中. 在其他图形API(dx,or opengl) ,glsetlinewidth驱动会 ...

  2. 实验吧Web-中-让我进去(Hash长度扩展攻击、加盐密码及Linux下hashpump的安装使用)

    打开网页,测试开始,注入费老大劲,看了大佬的blog才知道怎么干. bp抓包,观察发现cookie中有个source=0,在repeater中修改为source=1,然go一下,出来了一段源代码. $ ...

  3. 51nod1021:石子归并

    1021 石子归并 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合 ...

  4. tensorflow之最近邻算法实现

    最近邻算法,最直接的理解就是,输入数据的特征与已有数据的特征一一进行比对,最靠近哪一个就将输入数据划分为那一个所属的类,当然,以此来统计k个最靠近特征中所属类别最多的类,那就变成了k近邻算法.本博客同 ...

  5. 简单LCS HDU_1503

    学了一下最长公共子串,它是属于dp里面的 dp=max{(i,j-1),(i-1,j),(i-1,j-1)+d}问题,不得不说,规划方向确实厉害,当然这只适用于两个字符串匹配的问题,n个字符串的话,我 ...

  6. LCIS HDU - 3308 (线段树区间合并)

    LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...

  7. PAT B1045 快速排序

    题目如下: 1045 快速排序 (25 point(s)) 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到 ...

  8. tableau 和 R 的连接

    1.安装R包Rserve 2.tableau帮助-管理外部服务连接,单击测试按钮出现成功连接即是通信成功. 3.创建新工作表,设置id字段,针对id记录数创建计算字段Rrand.将Rrand拖入行维度 ...

  9. 当初希望自己是如何投入这个专业的学习的?曾经做过什么准备,或者立下过什么FLAG吗?

    学习好累,打游戏好爽  我不爱学习 认真勤勉投入学习 精心准备,刻苦学习 我的flag   作为大学生,需要了解今后职场社会,对职业方向有了进一步的认识.社会对于人才的要求在某些方面都是不谋而合的,比 ...

  10. 重载(overloading)和重写@Override

    一.重写:@Override 定义:字类方法覆盖父类方法,通俗来说就是方法里面的内容可以不一样,其他都一样. (1)必须保证权限大于等于父类的权限public>protetcted>默认& ...