C++常用的新特性-->day06

news2024/11/16 4:13:57

时间间隔duration

duration表示一段时间间隔,用来记录时间长度,可以表示几秒、几分钟、几个小时的时间间隔。duration的原型如下

// 定义于头文件 <chrono>
template<
    class Rep,
    class Period = std::ratio<1>
> class duration;

Rep:这是一个数值类型,表示时钟数(周期)的类型(默认为整形)。若 Rep 是浮点数,则 duration 能使用小数描述时钟周期的数目。
Period:表示时钟的周期,它的原型如下:

// 定义于头文件 <ratio>
template<
    std::intmax_t Num,
    std::intmax_t Denom = 1
> class ratio;

ratio类表示每个时钟周期的秒数,其中第一个模板参数Num代表分子,Denom代表分母,该分母值默认为1,因此,ratio代表的是一个分子除以分母的数值,比如:ratio<2>代表一个时钟周期是2秒,ratio<60>代表一分钟,ratio<6060>代表一个小时,ratio<6060*24>代表一天。而ratio<1,1000>代表的是1/1000秒,也就是1毫秒,ratio<1,1000000>代表一微秒,ratio<1,1000000000>代表一纳秒。

duration类的构造函数

// 1. 拷贝构造函数
duration( const duration& ) = default;
// 2. 通过指定时钟周期的类型来构造对象
template< class Rep2 >
constexpr explicit duration( const Rep2& r );
// 3. 通过指定时钟周期类型,和时钟周期长度来构造对象
template< class Rep2, class Period2 >
constexpr duration( const duration<Rep2,Period2>& d );

chrono库中根据duration类封装了不同长度的时钟周期(也可以自定义),基于这个时钟周期再进行周期次数的设置就可以得到总的时间间隔了(时钟周期 * 周期次数 = 总的时间间隔)。

综合案例

#include <chrono>
#include <iostream>
using namespace std;
int main()
{
    chrono::hours h(1);                          // 一小时
    chrono::milliseconds ms{ 3 };                // 3 毫秒
    chrono::duration<int, ratio<1000>> ks(3);    // 3000 秒

    // chrono::duration<int, ratio<1000>> d3(3.5);  // error
    chrono::duration<double> dd(6.6);               // 6.6 秒

    // 使用小数表示时钟周期的次数
    chrono::duration<double, ratio<1, 30>> hz(3.5);

    //count()统计的是时间周期
    cout << "count:" << h.count() << endl;
    cout << "count:" << ms.count() << endl;
    cout << "count:" << ks.count() << endl;
    cout << "count:" << dd.count() << endl;
    cout << "count:" << hz.count() << endl;

    cout << "************************************************************" << endl;

    chrono::milliseconds mss{ 3 };         // 3 毫秒
    chrono::microseconds uss = 2 * mss;     // 6000 微秒
    // 时间间隔周期为 1/30 秒 --> 一共有3.5个时间周期,每个周期为1/30秒
    chrono::duration<double, ratio<1, 30>> hzz(3.5);

    //count()统计的是时间周期
    cout << "3 ms duration has " << mss.count() << " ticks\n"
        << "6000 us duration has " << uss.count() << " ticks\n"
        << "3.5 hz duration has " << hzz.count() << " ticks\n";

    cout << "************************************************************" << endl;

    chrono::minutes t1(10);
    chrono::seconds t2(60);
    chrono::seconds t3 = t1 - t2;
    cout << t3.count() << " second" << endl;

    cout << "************************************************************" << endl;

 //统一时钟周期
    //分子的最大公约数是1 分母的最小公倍数是1 ---> 统一为ration<1,1>
    chrono::duration<int, ratio<60, 1>> jb(10);
    chrono::duration<int, ratio<1,1>> jk(60);
    auto jkb = jb - jk;
    cout << "count:" << jkb.count() << endl;

    cout << "************************************************************" << endl;
    
    //分子的最大公约数是3 分母的最小公倍数是35 ---> 统一为ration<3,35>
    chrono::duration<int, ratio<9, 7>> ak(3);
    chrono::duration<int, ratio<6, 5>> m4(1);
    auto hql = ak - m4;//auto --> chrono::duration<int,ration<3,35>>
    cout << "count:" << hql.count() << endl;
}

在这里插入图片描述

时间点和时钟

时间点结构体

hrono库中提供了一个表示时间点的类time_point,该类的定义如下:

// 定义于头文件 <chrono>
template<
    class Clock,
    class Duration = typename Clock::duration
> class time_point;

它被实现成如同存储一个 Duration 类型的自 Clock 的纪元起始开始的时间间隔的值,通过这个类最终可以得到时间中的某一个时间点。
Clock:此时间点在此时钟上计量
Duration:用于计量从纪元起时间的 std::chrono::duration 类型

时间点time_point构造函数

// 1. 构造一个以新纪元(epoch,即:1970.1.1)作为值的对象,需要和时钟类一起使用,不能单独使用该无参构造函数
time_point();
// 2. 构造一个对象,表示一个时间点,其中d的持续时间从epoch开始,需要和时钟类一起使用,不能单独使用该构造函数
explicit time_point( const duration& d );
// 3. 拷贝构造函数,构造与t相同时间点的对象,使用的时候需要指定模板参数
template< class Duration2 >
time_point( const time_point<Clock,Duration2>& t );

时钟clocks

system_clock:系统的时钟,系统的时钟可以修改,甚至可以网络对时,因此使用系统时间计算时间差可能不准。
steady_clock:是固定的时钟,相当于秒表。开始计时后,时间只会增长并且不能修改,适合用于记录程序耗时
high_resolution_clock:和时钟类 steady_clock 是等价的(是它的别名)。

在使用chrono提供的时钟类的时候,不需要创建类对象,直接调用类的静态方法就可以得到想要的时间了。

成员类型描述
rep表示时钟周期次数的有符号算术类型
period表示时钟计次周期的 std::ratio 类型
duration时间间隔,可以表示负时长
time_point表示在当前时钟里边记录的时间点

system_clock

时钟类system_clock是一个系统范围的实时时钟。system_clock提供了对当前时间点time_point的访问,将得到时间点转换为time_t类型的时间对象,就可以基于这个时间对象获取到当前的时间信息了。

system_clock底层源码

struct system_clock { // wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime
    using rep                       = long long;
    using period                    = ratio<1, 10'000'000>; // 100 nanoseconds
    using duration                  = chrono::duration<rep, period>;
    using time_point                = chrono::time_point<system_clock>;
    static constexpr bool is_steady = false;

    _NODISCARD static time_point now() noexcept 
    { // get current time
        return time_point(duration(_Xtime_get_ticks()));
    }

    _NODISCARD static __time64_t to_time_t(const time_point& _Time) noexcept 
    { // convert to __time64_t
        return duration_cast<seconds>(_Time.time_since_epoch()).count();
    }

    _NODISCARD static time_point from_time_t(__time64_t _Tm) noexcept 
    { // convert from __time64_t
        return time_point{seconds{_Tm}};
    }
};

静态方法

// 返回表示当前时间的时间点。
static std::chrono::time_point<std::chrono::system_clock> now() noexcept;
// 将 time_point 时间点类型转换为 std::time_t 类型
static std::time_t to_time_t( const time_point& t ) noexcept;
// 将 std::time_t 类型转换为 time_point 时间点类型
static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;

system_clock案例

#define _CRT_SECURE_NO_WARNINGS

#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;
int main()
{
    // 新纪元1970.1.1时间
    system_clock::time_point epoch;
    
    chrono::hours h(10 * 24);
    system_clock::time_point epoch1 = epoch + h;
    system_clock::time_point epoch2(epoch + h);

    //当前的时间
    system_clock::time_point nowTime = system_clock::now();
    //时间点 -> 时间段(单位秒)
    time_t allSec = system_clock::to_time_t(nowTime);
    //时间格式化 -> 通过ctime转化为字符串
    cout << "当前的时间:" << ctime(&allSec) << endl;

    //时间段转化为时间点
    system_clock::time_point tp = system_clock::from_time_t(allSec);
}

steady_clock

在C++11中提供的时钟类steady_clock相当于秒表,只要启动就会进行时间的累加,并且不能被修改,非常适合于进行耗时的统计。

底层源码

struct steady_clock { // wraps QueryPerformanceCounter
    using rep                       = long long;
    using period                    = nano;
    using duration                  = nanoseconds;
    using time_point                = chrono::time_point<steady_clock>;
    static constexpr bool is_steady = true;

    // get current time
    _NODISCARD static time_point now() noexcept 
    { 
        // doesn't change after system boot
        const long long _Freq = _Query_perf_frequency(); 
        const long long _Ctr  = _Query_perf_counter();
        static_assert(period::num == 1, "This assumes period::num == 1.");
        const long long _Whole = (_Ctr / _Freq) * period::den;
        const long long _Part  = (_Ctr % _Freq) * period::den / _Freq;
        return time_point(duration(_Whole + _Part));
    }
};

静态方法

static std::chrono::time_point<std::chrono::steady_clock> now() noexcept;

案例

#define _CRT_SECURE_NO_WARNINGS

#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;

void steadyClockTest()
{
	auto p1 = steady_clock::now();
	for (int i = 0; i < 100; i++)
	{
		cout << "*";
	}
	cout << endl;
	auto p2 = steady_clock::now();
	auto d1 = p2 - p1;
	cout << "count:" << d1.count() << endl;
}

int main()
{
	steadyClockTest();
	return 0;
}

在这里插入图片描述
得到的值是纳秒,去掉9个0换算成秒

high_resolution_clock

同system_clock

转换函数

如果是对时钟周期进行转换:源时钟周期必须能够整除目的时钟周期(比如:小时到分钟)。
如果是对时钟周期次数的类型进行转换:低等类型默认可以向高等类型进行转换(比如:int 转 double)。
如果时钟周期和时钟周期次数类型都变了,根据第二点进行推导(也就是看时间周期次数类型)。
以上条件都不满足,那么就需要使用 duration_cast 进行显示转换。

duration_cast

通过这个函数可以对duration类对象内部的时钟周期Period,和周期次数的类型Rep进行修改

#define _CRT_SECURE_NO_WARNINGS

#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;

void durationCastTest()
{
	//分钟 -> 小时 
	hours h = duration_cast<hours>(minutes(60));
	cout << "60 minutes is " << h.count() << " hours\n";
	//小时 -> 分钟
	minutes m1 = hours(1);
	cout << "1 hour is " << m1.count() << " minutes\n";

	//浮点 -> 整形 --> 不建议会损失精度
	//seconds ss = duration<double> s(2.5);//err 
	seconds ss1 = duration_cast<seconds>(duration<double> (2.5));

	using mydouble = duration<double>;
	seconds ss2 = duration_cast<seconds>(mydouble(2.5));
	cout << "ss1.count():" << ss1.count() << endl;
	cout << "ss2.count():" << ss2.count() << endl;

	//整形 -> 浮点
	mydouble dd = seconds(9);
	cout << "dd.count():" << dd.count() << endl;

	//时钟周期数据类型和时钟周期都变了
	duration<int, ratio<1, 100>>t1(100);
	duration<double, ratio<1, 100>>t2(12.56);

	//duration<int, ratio<1, 100>>t3 = t2;//err double转int有问题
	duration<int, ratio<1, 100>>t3 = duration_cast<duration<int, ratio<1, 100>>>(t2);
	cout << "t3.count():" << t3.count() << endl;
	duration<double, ratio<1, 100>>t4 = t1;// >>>> 时钟周期和时钟周期的数据类型都不相同,看类型转化,由于是int转double是没问题的-->会进行隐式类型转化
	cout << "t4.count():" << t4.count() << endl;
}

int main()
{
	durationCastTest();
	return 0;
}

在这里插入图片描述

time_point_cast

函数的作用是对时间点进行转换,因为不同的时间点对象内部的时钟周期Period,和周期次数的类型Rep可能也是不同的

#define _CRT_SECURE_NO_WARNINGS

#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;

void durationCastTest()
{
	//分钟 -> 小时 
	hours h = duration_cast<hours>(minutes(60));
	cout << "60 minutes is " << h.count() << " hours\n";
	//小时 -> 分钟
	minutes m1 = hours(1);
	cout << "1 hour is " << m1.count() << " minutes\n";

	//浮点 -> 整形 --> 不建议会损失精度
	//seconds ss = duration<double> (2.5);//err 
/*
	template< class Rep2 >
	constexpr explicit duration( const Rep2& r );
*/
	seconds ss1 = duration_cast<seconds>(duration<double> (2.5));

	using mydouble = duration<double>;
	seconds ss2 = duration_cast<seconds>(mydouble(2.5));

	duration<double>a(2.5);
	seconds ss3 = duration_cast<seconds>(a);

	cout << "ss1.count():" << ss1.count() << endl;
	cout << "ss2.count():" << ss2.count() << endl;
	cout << "ss3.count():" << ss3.count() << endl;

	//整形 -> 浮点
	mydouble dd = seconds(9);
	cout << "dd.count():" << dd.count() << endl;

	//时钟周期数据类型和时钟周期都变了
	duration<int, ratio<1, 100>>t1(100);
	duration<double, ratio<1, 100>>t2(12.56);

	//duration<int, ratio<1, 100>>t3 = t2;//err double转int有问题
	duration<int, ratio<1, 100>>t3 = duration_cast<duration<int, ratio<1, 100>>>(t2);
	cout << "t3.count():" << t3.count() << endl;
	duration<double, ratio<1, 100>>t4 = t1;// >>>> 时钟周期和时钟周期的数据类型都不相同,看类型转化,由于是int转double是没问题的-->会进行隐式类型转化
	cout << "t4.count():" << t4.count() << endl;
}

//时间段传入
template<typename Duration>
using MyTimePoint = time_point<system_clock, Duration>;

int main()
{
	durationCastTest();
	cout << "********************************" << endl;
	MyTimePoint<seconds> mPoint(seconds(100));
	MyTimePoint<milliseconds> millPoint(milliseconds(1000));

	//s->ms
	MyTimePoint<milliseconds> ms = mPoint;
	time_t tm1 = system_clock::to_time_t(ms);//时间点转化
	cout << "  " << ctime(&tm1);

	//ms->s
	//MyTimePoint<seconds> mss = millPoint;//err >>>>  
	MyTimePoint<seconds> mss = time_point_cast<seconds>(millPoint);
	time_t tm2 = system_clock::to_time_t(mss);
	cout << "  " << ctime(&tm2);

	return 0;
}

在这里插入图片描述

作者: 苏丙榅
链接: https://subingwen.cn/cpp/chrono/#1-2-%E7%B1%BB%E7%9A%84%E4%BD%BF%E7%94%A8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2241258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cyberchef配合Wireshark提取并解析TCP/FTP流量数据包中的文件

前一篇文章中讲述了如何使用cyberchef提取HTTP/TLS数据包中的文件,详见《Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件》,链接这里,本文讲述下如何使用cyberchef提取FTP/TCP数据包中的文件。 FTP 是最为常见的文件传输协议,和HTTP协议不同的是FTP协议传输…

性能面向下一代PCIe Gen 5,G991B322HR、G99L12312HR 安费诺ExtremePort™ Swift连接器支持内部I/O应用

前言 为了在网络设备和服务器上提供更高速度和更小尺寸的解决方案&#xff0c;Amphenol开发了ExtremePort™ Swift连接器&#xff0c;适用于PCIe Gen5 NRZ 32GT/s、UPI 2.0 24GT/s、24Gb/s SAS信号。 G991B322HR G9912312HR G9912322HR G9914312HR G991B312HR G991C312HR G99…

IDEA调整警告级别【IntelliJ IDEA 2024.2.0.1】

文章目录 目前现状鼠标悬停&#xff0c;选择配置筛选 > 取消选择OK效果 目前现状 需要把提示改成只要显示error的5个 鼠标悬停&#xff0c;选择配置 筛选 > 取消选择 OK 效果

【二叉搜素树】——LeetCode二叉树问题集锦:6个实用题目和解题思路

文章目录 计算布尔二叉树的值求根节点到叶节点的数字之和二叉树剪枝验证二叉搜索树二叉搜索树中第K小的元素二叉树的所有路径 计算布尔二叉树的值 解题思路&#xff1a; 这是一个二叉树的布尔评估问题。树的每个节点包含一个值&#xff0c;其中叶子节点值为 0 或 1&#xff0…

windows下QT5.12.11使用MSVC编译器编译mysql驱动并使用详解

1、下载mysql开发库,后面驱动编译的时候需要引用到,下载地址:mysql开发库下载 2、使用everything搜索:msvc-version.conf,用记事本打开,添加:QMAKE_MSC_VER=1909。不然msvc下的mysql源码加载不上。

Isaac Sim+SKRL机器人并行强化学习

目录 Isaac Sim介绍 OmniIssacGymEnvs安装 SKRL安装与测试 基于UR5的机械臂Reach强化学习测评 机器人控制 OMNI GYM环境编写 SKRL运行文件 训练结果与速度对比 结果分析 运行体验与建议 Isaac Sim介绍 Isaac Sim是英伟达出的一款机器人仿真平台&#xff0c;适用于做机…

删库跑路,启动!

起因&#xff1a;这是一个悲伤的故事&#xff0c;在抓logcat时 device待机自动回根目录了&#xff0c;而题主对当前路径的印象还停留在文件夹下&#xff0c;不小心在根目录执行了rm -rf * … 所以&#xff0c;这是个悲伤的故事&#xff0c;东西全没了…device也黑屏了&#xff…

CSS的综合应用例子(网页制作)

这是html的一些最基本内容的代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <t…

SobarQube实现PDF报告导出

文章目录 前言一、插件配置二、使用步骤1.新生成一个Token2.将拷贝的Token加到上文中执行的命令中3.查看报告 三、友情提示总结 前言 这篇博文是承接此文 .Net项目在Windows中使用sonarqube进行代码质量扫描的详细操作配置 描述如何导出PDF报告 众所周知&#xff0c;导出PDF功…

力扣-Mysql-3328-查找每个州的城市 II(中等)

一、题目来源 3328. 查找每个州的城市 II - 力扣&#xff08;LeetCode&#xff09; 二、数据表结构 表&#xff1a;cities ---------------------- | Column Name | Type | ---------------------- | state | varchar | | city | varchar | ----------------…

curl命令提交大json

有个客户需要提交一个4M左右的pdf&#xff0c;接口里传的是pdf字节流base64编码后的字符串。 直接curl -XPOST -d json串 api接口会报 参数过长报错Argument list too long 网上搜了下解决方案把json串放到文本里然后通过json.txt引入参数 这一试不要紧&#xff0c;差点儿导致…

gitlab和jenkins连接

一&#xff1a;jenkins 配置 安装gitlab插件 生成密钥 id_rsa 要上传到jenkins&#xff0c;id_rsa.pub要上传到gitlab cat /root/.ssh/id_rsa 复制查看的内容 可以看到已经成功创建出来了对于gitlab的认证凭据 二&#xff1a;配置gitlab cat /root/.ssh/id_rsa.pub 复制查…

<项目代码>YOLOv8 玉米地杂草识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

Ubuntu+ROS 机械臂拾取和放置

官方链接&#xff1a;https://github.com/skumra/baxter-pnp 1.下载并安装 SDK 依赖项 sudo apt-get install python-wstool python-rosdep 2.创建新的 catkin 工作区 mkdir -p ~/ros_ws/src cd ~/ros_ws/src 3.使用 wstool 下载 rosinstall 文件并将其复制到 Catkin 工作区…

【Linux学习】【Ubuntu入门】1-4 ubuntu终端操作与shell命令1

1.使用快捷键CtrlAltT打开命令终端&#xff0c;或者单击右键点击… 2.常用shell命令 目录信息查看命令&#xff1a;ls ls -a&#xff1a;显示目录所有文件及文件夹&#xff0c;包括隐藏文件&#xff0c;比如以.开头的 ls -l&#xff1a;显示文件的详细信息 ls -al&#xff1…

【含开题报告+文档+PPT+源码】基于springboot的毕业设计选题管理系统

开题报告 毕业设计选题作为高校教学环节中的重要一环&#xff0c;其选题质量和管理效率直接关系到学生毕业设计的质量和毕业要求的达成。然而&#xff0c;传统的选题管理方式往往存在信息不对称、流程繁琐、效率低下等问题&#xff0c;无法满足高校教学管理现代化、信息化的需…

第四十二章 Vue中使用mutations修改Vuex仓库数据

目录 一、mutations修改仓库数据 1.1. 概述 1.2. mutations修改数据基本步骤 1.3. 完整代码 1.3.1. main.js 1.3.2. App.vue 1.3.3. index.js 1.3.4. Son1.vue 1.3.5. Son2.vue 二、mutations传参语法 2.1. mutations传参基本步骤 2.2. 完整代码 2.2.1. index.js …

【MYSQL】锁详解(全局锁、表级锁、行级锁)【快速理解】

目录 一、全局锁 二、表级锁 1.表锁 2.元数据锁 3.意向锁 三、行级锁 1. 行锁 2.间隙锁 3.临建锁 锁是处理并发情况下&#xff0c;对数据的一致性的关键因素&#xff0c;也是并发情况下对效率影响非常大的。 1、全局锁&#xff1a;锁定表中所有数据。 2、表级锁&#xff1a;…

客户案例|智能进化:通过大模型重塑企业智能客服体验

01 概 述 随着人工智能技术的快速发展&#xff0c;客户对服务体验的期待和需求不断升级。在此背景下&#xff0c;大模型技术的崛起&#xff0c;为智能客服领域带来了创造性的变革。 在上篇文章《在后LLM时代&#xff0c;关于新一代智能体的思考》中有提到&#xff0c;智能客服…

【Leetcode 中等】34. 在排序数组中查找元素的第一个和最后一个位置

原题链接 Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置 题目 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必…