duration (持续时间) 是定义为时间刻度数的时间间隔,可以指定一个时间刻度是多少秒。因此,时间刻度是衡量时间长短的基础。duration 模板的实例类型的对象定义了 duration。时间刻度所表示的默认时间间隔是 1 秒,但可以将它定义为更多秒或秒几分之一。例如,如果定义时间刻度为 3600 秒,但意味着 10 个 duration 就是 10 个小时;也能够定义时间刻度为一秒的十分之一,在这种情况下,10 个 duration 表示 1 秒。

定义 duration

chrono 头文件中的 std::chrono::duration 模板类型表不 duration。模板参数 T 是值的类型,一般是基本的算术类型,并且参数 P 对应的值是时间刻度所表示的秒数,它所对应的值为 1 秒。必须用 ratio 类型指定 P 的值,默认为 ratio<1>。下面是 duration 的一些示例:

std::chrono::duration IBM650_divide {15}; // A tick is 1 millisecond so 15 milliseconds std::chrono::duration minute {60}; // A tick is 1 second by default so 60 seconds

std::chrono::duration>hour {60}; // A tick is 60 seconds so 60 minutes

//A tick is a microsecond so 1 millisecond std::chrono::duration millisec {1000L};

//A tick is fifth of a second so 1.1 seconds

std::chrono::duration> tiny {5.5};

第 1 条语句使用从 ratio 头文件中获取的对应于 ratio<1,1000> 的别名 milli。第 2 条语句省略了第二个模板参数的值,因此是 ratio<1>,这意味着持续时间以 1 秒为单位。

在第 3 条语句中,ratio<60> 模板参数值指定了时间刻度为 60 秒,因此 hour 对象的值是按分钟测量的,它的初值表示 1 小时。

第 4 条语句使用了 ratio 头定义的 micro 类型来定义 ratio<1, 1000000>,因此 tick 是毫秒,millisec 变量有一个表示毫秒的初值。最后一条语句定义了一个时间刻度为 1/5 秒的对象,初值是 5.5 的五分之一,它是 1.1 秒。

chrono 头文件为有整数类型值的常用持续时间类型在 std::chrono 命名空间中定义了别名。标准别名是:

nanoseconds microsecondsmilliseconds seconds minutes> hours>

这些别名中,每个整数类型的持续时间值都取决于实现,但 C++14 标准要求 duration 至少为 292 年,可以是正数或负数。在笔者系统上小时和分钟类型将 duration 保存为 int 类型,将其他的保存为 long long 类型。因此前面的代码段可以这样定义 millisec 变量:

std::chrono::microseconds millisec {1000}; // Duration is type long long on my system

当然,这个定义和原始定义不同。变量的初值表示的是相同的时间间隔(1 毫秒)但这里持续时间的单位是 1 毫秒,而在先前的代码中是 1 微秒。前面的 millisec 的定义许更精确地表示持续时间。

所有可以应用到 duration 对象的算术运算符,都可以被用到左操作数是 duration 对象的复合赋值中,+= 和 -+ 这些运算的右操作数必须是 duration 对象。*= 和 /= 的右操作数必须和作为左操作数的时间刻度数有相同类型的数值,或者可以隐式转换为数值。%= 的右操作数可以是 duration 对象或数值。它们中的每一个都能产生我们期望的结果。例如下面使用 += 的代码:

std::chrono:imilliseconds millisec {1}; // Duration is also type long long on my system

第一个 += 运算的操作数为相同类型,作为右操作的对象所保存的值会被加到左操作数上。第二个 += 运算的操作数为不同类型,但右操作数会被隐式转换为左操作的类型。这是可能的,因为转换是向有较短时间刻度的 duration 类型转换的。如果向相反的方向转换就不行,所以不能在 += 运算中用 long_time 作为左操作数、用 short_time 作为右操作数。

duration之间的算术运算

可以将前缀或后缀自增和自减运算符应用到 duration 对象上,并且可以通过调用成员函数 count() 来得到时间刻度数。下面是示例代码:

std::chrono::duration> tiny {5.5}; // Measured in 1/5 second

std::chrono::microseconds very_tiny {100}; // Measured in microseconds

++tiny;

very_tiny--;

std::cout << "tiny = " << tiny.count()<< " very_tiny = " << very_tiny.count()<< std::endl; // tiny = 6.5 very_tiny = 99

可以将任何二元算术运算符 +、-、*、/、% 应用到 duration 对象上,会得到一个 duration 对象作为结果。这些都是作为非成员运算符函数实现的。下面是一个示例:

std::chrono::duration> tiny {5.5}; std::chrono::duration> small {7.5};

auto total = tiny + small;

std::cout << "total = " << total.count() << std::endl;

// total = 13

算术运算符也可以用不同类型的 std::chrono::duration 模板实例作为操作数,模板的两个参数都可以不同。这是通过使用 common_type 模板的特化将两个操作数转换为它们的共有类型来实现的,common_type 定义在 type_traits 头文件中。对于 duration 和 duration 类型的参数,返回值为 duration 类型 duration。T3 是 T1 和 T2 的共有类型。这些类型是通过将算术运算应用到这些类型的值来得到的。

P3 是 P1 和 P2 的最大公因数。有一个示例会更清楚一些:

std::chrono:imilliseconds ten_minutes {600000}; // A tick is 1 millisecond so 10 minutes

std::chrono::minutes half_hour {30}; // A tick is 1 minute so 30 minutes

auto total = ten_minutes + half_hour; // 40 minutes in common tick period

std::cout <

// total = 2400000

加法的结果是 40 分钟,因此可以推断出 total 是毫秒类型的对象。下面是另一个示例:

std::chrono::minutes ten_minutes {10}; // 10 minutes

std::chrono::duration> interval {4500.0}; // 15 minutes

auto total_minutes = ten_minutes + interval;

std::cout << "total minutes = " << total_minutes.count()<< std::endl;

// total minutes = 7500

total_minutes 的值是 double 类型。我们知道结果必定是 25 分钟,也就是 1500 秒;结果为 7500,因此时间刻度的长度为 ratio<1,5>,即 1/5 秒。最好尽可能地避免对混合的 duration 类型进行算术运算,因为很容易不知道时间刻度是什么。

所有可以应用到 duration 对象的算术运算都可以用到左操作数是 duration 的复合赋值中。+= 和 -= 的右操作数必须是 duration 对象。*= 和 /= 的右操作数必须和左操作数的时钟刻度类型相同,或者可以隐式转换为那种类型。%= 的右操作数可以是 duration 对象或数值。它们中的每一个都能产生我们想要的结果。例如,下面是使用 += 的示例:

std::chrono::minutes short_time {20};

std::chrono::minutes shorter_time {10};

short_time += shorter_time; // 30 minutes

std::chrono::hours long_time {3}; // 3hrs = 180 minutes

short_time += long_time;

std::cout << "short_time = " << short_time.count() << std::endl;

// short_time = 210

第一个 += 运算的操作数都为相同类型,因此右操作对象保存的值会被加到左操作数上。第二个 += 运算的操作数为不同类型,但是右操作数可以隐式转换为左操作数的类型。这是可能的,因为转换的是短时钟周期的 duration 类型。相反,就不能转换,因此不能在用 += 时以 long_time 作为左操作数,以 short_time 作为右操作数。

duration类型之间的转换

通常,一个 duration 类型总是可以被隐式转换为另一个 duration 类型,如果它们都是浮点型 duration 值的话。当源类型的时钟周期是目的类型的时钟周期的整数倍时,只能对整数值进行隐式转换。下面是一些示例:

std::chrono::duration> d1 {50}; // 10 seconds

std::chrono::duration> d2 {50}; // 5 seconds

std::chrono::duration> d3 {45}; // 15 seconds

std::chrono::duration> d4 {60}; // 10 seconds

d2 += d1; // OK - implicit conversion of d1

d1 += d2; // Won't compile 1/10 not a multiple of 1/5

d1 += d3; // Won't compile 1/3 not a multiple of 1/5

d4 += d3; //OK - implicit conversion of d3

可以显式地使用 dumtion_cast 模板进行强制转换。下面是一个示例,假设 d1 和 d2 都有上述代码定义的初值:

d1 += std::chrono::duration_cast<:chrono::duration std::ratio>>>(d2);

std::cout << d1.count() << std::endl; // 75 - i.e.15 seconds

第一条语句会用 duration_cast 来使 d2 加到 d1 的运算能够进行。在这个示例中,结果是准确的,但并不总是如此。例如:

std::chrono::duration> d1 {50}; // 10 seconds

std::chrono::duration> d2 {53}; // 5.3 seconds

d1 += std::chrono::duration_cast<:chrono::duration std::ratio>>>(d2);

std::cout << d1.count() << std::endl; // 76 - i.e. 15.2 seconds

不能将 duration 值 d1 和 d2 的和表示成 0.2 秒的整数倍,因此结果值稍微超出了。如果 d2 的值是 54,得到的正确结果应该是 77。

duration 类型支持赋值,因此可以将一个 duration 对象的值赋给另一个 duration 对象。如果与这一节开始时描述的条件相符,就可以使用隐式转换;否则需要对右操作数显式转换。例如,可以这样写:

std::chrono::duration> d1 {50}; // 10 seconds

std::chrono::duration> d2 {53}; // 5.3 seconds

d2 = d1; // d2 is 100 = 10 seconds

比较 duration

有一整套完整的运算符可以用来比较两个 duration 对象。它们都是由非成员函数实现的,允许比较不同类型的 duration 对象。这个过程可以确定操作数共同的时钟周期,当表示成相同的时钟周期时,就可以比较 duration 的值。例如:

std::chrono::duration> d1 {50}; // 10 seconds

std::chrono::duratior> d2 {50}; // 5 seconds

std::chrono::duration> d3 {45}; // 15 seconds

if ((d1 - d2) == (d3 - d1))

std::cout << "both durations are "<<:chrono::duration_cast d2 seconds std::endl>

这里显示了从算术运算得到的 duration 对象的比较方法。它们是相等的,当然也会产生这样的输出。seconds 类型的强制转换允许秒数表示成整数,而不用管结果为 duration 类型。如果想使用非整数的秒数值,可以强制转换为 dumtion 类型。

duration 常量

chrono 头文件中定义了可以让我们指定 duration 对象的常量的运算符。这些运算符被定义在命名空间 std::literals::chrono_literals 中,命名空间 literals 和 chrono_literals 都是内联的。有了下面的声明之后,就可以对 duration 常量使用常量运算符:

using namespace std::literals::chrono_literals;

但是,如果指定了下面的声明,上面的声明会被自动包含:

using namespace std::chrono;

可以将 duration 常量指定为整数或浮点值,后缀指定了时钟周期。这里有 6 个可以使用的后缀:

h 是小时,例如 3h 或 3.5h。

min 是分钟,例如 20min 或 3.5min。

s 是秒,例如 10s 或 1.5s。

ms 是毫秒,例如 500ms 或 1.5ms。

us 是微秒,例如 500us 或 0.5uso

ns 是纳秒,例如 2ns 或 3.5ns。

如果一个 duration 常量有整数值,它会从这些被定义在 chrono 头文件中的常量得到一个合适的别名。因此 24h 是一个 std::chrono::hours 类型的常量,25ms 的类型是 std::chrono::milliseconds。如果常量的值不是整数,这个常量会是浮点值类型的 duration 类型。浮点值的周期取决于后缀;对于后缀 h、min、s、ms、us 和 n,时钟周期分别为 ratio<3600>、ratio<60>、 ratio<1>、milli、micro 和 nano。

下面举例说明使用它们的一些方式:

using namespace std::literals::chrono_literals;

std::chrono::seconds elapsed {10}; // 10 seconds

elapsed += 2min; // Adding type minutes to type seconds: 130 seconds

elapsed -= 15s; // 115 seconds

如示例所示,当需要改变间隔的长短时,duration 常量是非常有用的。需要记住的是,为了能够进行算术运算,作为右操作数的时钟周期必须是作为左操作数的时钟周期的整数倍。例如:

elapsed += 100ns; // Won't compile!

变量 lapsed 的时钟周期为 1,不能向它加一个周期小于 1 的 duration。

可以用常量将同类型的变量定义为常量。例如:

auto some_time = 10s; // Variable of type seconds, value 10

elapsed = 3min - some_time;// Set to difference between literal and variable: result 170

some_time *= 2; // Doubles the value - now 20s

const auto FIVE_SEC = 5s; // Cannot be changed

elapsed = 2s + (elapsed - FIVE_SEC)/5;

// Result 35

这里,some_time 是一个 seconds 类型的变量,它的类型为 duration>,值为 10。第 3 条语句说明可以改变 some_time 的值。FIVE_SEC 是 const seconds 类型的值,因此不能改变它的值。最后一条语句展示了一个包含一个 duration 常量、一个 duration 变量、一个常量类型的 seconds 对象,以及一个整数常量的算术表达式。

matlab中duration是什么意思,C++ duration(STL duration)模板用法详解相关推荐

  1. python中values是什么意思_Python values()与itervalues()的用法详解

    dict 对象有一个 values() 方法,这个方法把dict转换成一个包含所有value的list,这样,我们迭代的就是 dict的每一个 value: d = { 'Adam': 95, 'Li ...

  2. linux中grep命令 菜鸟教程,linux grep正则表达式与grep用法详解

    需要大家牢记:正则表达式与通配符不一样,它们表示的含义并不相同 正则表达式只是字符串的一种描述,只有和支持正则表达式的工具相结合才能进行字符串处理.本文以grep为例来讲解正则表达式. grep命令 ...

  3. python中os.path.join()的循环用法_Python中.join()和os.path.join()两个函数的用法详解

    Python中有.join()和os.path.join()两个函数,具体作用如下: . join():    连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 ...

  4. python3 join函数_Python中.join()和os.path.join()两个函数的用法详解

    Python中有.join()和os.path.join()两个函数,具体作用如下: . join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 '' ...

  5. linux中mkswap命令使用方法,mkswap命令_Linux mkswap 命令用法详解:建立和设置SWAP交换分区...

    mkswap命令用于在一个文件或者设备上建立交换分区.在建立完之后要使用sawpon命令开始使用这个交换区.最后一个选择性参数指定了交换区的大小,但是这个参数是为了向后兼容设置的,没有使用的必要,一般 ...

  6. SQL中的left outer join,inner join,right outer join用法详解1

    LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行. LEFT JOIN 关键字语法 SELECT column_ ...

  7. html中字段是日期控件,jQuery日历插件datepicker用法详解

    jQuery是一款不可多得的非常优秀的javascript脚本开发库,而基于其上的很多插件也是非常规范和卓越的,如果错过这番美景真是太可惜了,比如datepicker这个插件. 一般MIS系统的前端, ...

  8. c语言中整形变量,C语言基本数据类型:整型(int)用法详解

    1.整型int C语言提供了很多整数类型(整型),这些整型的区别在于它们的取值范围的大小,以及是否可以为负.int是整型之一,一般被称为整型.以后,在不产生歧义的情况下,我们把整数类型和int都称为整 ...

  9. SQL中的left outer join,inner join,right outer join用法详解

    SQL提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同. 连接类型                                       ...

最新文章

  1. Git学习系列之一些常用的Git命令收录更新ing
  2. 三层架构用户登录代码c语言,三层架构实现简单的用户登录代码
  3. mvc3中正确处理ajax访问需要登录的页面
  4. JavaScript中的循环
  5. 关于mousemove和scroll事件的一点技巧
  6. centos linux asp,CentOS 7.4 下 如何部署 AspNetCore 结合 consul
  7. C++类的构造函数、析构函数与赋值函数
  8. Mac端SVN工具CornerStone详解
  9. Win7 下安装 Sketsa.SVG.Editor v7.0.1
  10. vscode启动项目报jdk11没有_JDK 11 安装过程(同时已安装了JDK 8)以及Intellij IDEA 配置...
  11. HTMLUnit爬虫模拟登录Linkedin
  12. mysql coreseek_关于mysql中文全文检索Sphinx之coreseek
  13. 企业资源计划(ERP)原理与实践第一章
  14. windows下System Volume Information Folder文件夹过大的处理
  15. 计算机2级选择题及答案,计算机二级Office模拟试题及答案
  16. Defender绝密档案:惊现中本聪?
  17. python知识点智能问答_【每日一荐】智能问答API
  18. Linux学习笔记 Day0
  19. JAVASCRIPT中THIS指的是什么?
  20. project-clean的作用

热门文章

  1. 远程医疗中使用AR眼镜,内窥镜,视频远程诊疗方案
  2. win10 修复打印机服务器,Windows Update修复了打印机错误(win10/win7)
  3. python爬取凤凰新闻网_python3.6爬取凤凰网新闻-爬虫框架式思维
  4. 从视图索引说Notes数据库
  5. linux 内核 空指针,Linux 内核IS_ERR函数
  6. Lora SX1278芯片 模块引脚的功能介绍
  7. 服务器ping返回信息,如何ping服务器线路?ping命令的用法
  8. 目标检测:PASCAL VOC 数据集简介
  9. protobuf repeated数组类型的使用
  10. 依锥彻怕燎方跃涣牧叵邻牟辟岗俅