this_thread::sleep_for()和chrono::duration, ratio;

Friday, August 14, 2020

想着找个跨平台的 sleep() , 看到了标准库里的 sleep_for() , 用起来不难, 但涉及到一些没见过的类

TL;DR

C++11

using namespace std;
this_thread::sleep_for(chrono::milliseconds(500));
this_thread::sleep_for(chrono::seconds(2));
this_thread::sleep_for(chrono::minutes(1));

C++14

using namespace std;
using namespace std::chrono_literals;
this_thread::sleep_for(500ms);
this_thread::sleep_for(2s);
this_thread::sleep_for(1min);

std::this_thread::sleep_for

header: <thread>

template< class Rep, class Period >
void sleep_for( const std::chrono::duration<Rep, Period>& sleep_duration );

阻塞当前线程至少一个 sleep_duration (可能会由于调度或者资源竞争产生延迟)

显然我们需要构造一个 duration 对象来表示要阻塞的时间

std::chrono::duration

header: <chrono>

template<
    class Rep, 
    class Period = std::ratio<1> 
> class duration;

Rep 是一个数值类型, 如: int , double

Period 表示时间周期, 单位是秒, 默认是1秒 ( std::ratio 类用来表示一个有理数, 将在后面讲解)

一个 duration 对象内唯一的数据是一个 Rep 类型的数, 用来表示时间

std::chrono::duration<int> tow_sec(2); // 一个表示2秒的duration对象
std::chrono::duration<double, std::ratio<60>> half_min(0.5); // 一个表示半分钟的duration对象
std::chrono::duration<int, std::ratio<1, 1000>> five_hundred_milli(500); // 一个表示500毫秒的duration对象

C++11中预先定义好的常用类型

TypeDefinition
std::chrono::nanosecondsduration</*signed integer type of at least 64 bits*/, std::nano>
std::chrono::microsecondsduration</*signed integer type of at least 55 bits*/, std::micro>
std::chrono::millisecondsduration</*signed integer type of at least 45 bits*/, std::milli>
std::chrono::secondsduration</*signed integer type of at least 35 bits*/>
std::chrono::minutesduration</*signed integer type of at least 29 bits*/, std::ratio<60>>
std::chrono::hoursduration</*signed integer type of at least 23 bits*/, std::ratio<3600>>

C++14

C++14在标准库里添加了几个函数, 使得 duration 的使用变得相当友好, 就像博客开头那样

Defined in inline namespace std::literals::chrono_literals

FunctionIntroduction
operator"“h (C++14)A std::chrono::duration literal representing hours (function)
operator"“min (C++14)A std::chrono::duration literal representing minutes (function)
operator"“s (C++14)A std::chrono::duration literal representing seconds (function)
operator"“ms (C++14)A std::chrono::duration literal representing milliseconds (function)
operator"“us (C++14)A std::chrono::duration literal representing microseconds (function)
operator"“ns (C++14)A std::chrono::duration literal representing nanoseconds (function)

std::ratio

header: <ratio>

template< 
    std::intmax_t Num, 
    std::intmax_t Denom = 1 
> class ratio;

ratio 以分数的形式来保存有理数, Num 表示分子, Denom 表示分母, 分母默认为1

ration 定义了两个静态数据成员 numden 来保存分子和分母, 可以通过 对象名::num对象名::den 直接获取相应数据

从模板声明可以看出来, 不同有理数的类型并不一样, 直接重载算术运算符没有什么意义, 要对有理数进行运算需要用 <ratio> 头文件里定义的类

下面是c++官方文档给出的将两个有理数相加的 Example:

#include <iostream>
#include <ratio>
 
int main()
{
    typedef std::ratio<2, 3> two_third;
    typedef std::ratio<1, 6> one_sixth;
 
    typedef std::ratio_add<two_third, one_sixth> sum;
    std::cout << "2/3 + 1/6 = " << sum::num << '/' << sum::den << '\n';
}

output:

2/3 + 1/6 = 5/6

参考:

cpp

浮点数比较

QML实现图片圆角