C++11 std::chrono::duration

[Original] C++ new standard std::chrono::duration

Original summary C++11 chrono duration ratio 

 

Overview

The new C++ standard provides a new thread library. Recently, when writing test code, you need to put the current thread to sleep. Just call the Sleep() provided by windows directly . In the new standard, you can use std::this_thread::sleep_for() Or std::this_thread::sleep_until()
to achieve sleep. Which involves std::chrono::duration and std::chrono::time_point . This article only summarizes std::chrono::duration , std::chrono::time_point will write another summary.

std::chrono::duration

description

std::chrono::duration is defined in the file and is used to represent a time period.

The original words on cppreference are as follows:

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.

RepThe parameter represents the type of time unit that can be passed in , which can be float, int, int64, etc. If it is float, it means that part of the time unit can be passed in. For example, passing in 1.2 means 1.2 times the time unit .
PeriodThe parameter represents the time unit , which can be microseconds, milliseconds, seconds, minutes, hours, etc. (or other custom units, the type is std::ratio ).

Note:

  1. The tick mentioned above can be understood as a period, or a unit of time.
  2. The number of seconds  indicates that the period value is calculated based on seconds.

Class definition

std::chrono::duration is a template class. The key code is excerpted as follows (the format has been adjusted):

template<class _Rep, class _Period> 
class duration { 
public: 
    typedef duration<_Rep, _Period> _Myt; 
    typedef _Rep rep; 
    typedef _Period period; 
     
    // constructor, save param to _MyRep, used by count() member function. 
    template<class _Rep2, 
    class = typename enable_if<is_convertible<_Rep2, _Rep>::value 
        && (treat_as_floating_point<_Rep>::value || !treat_as_floating_point<_Rep2>::value), 
        void>::type> 
    constexpr explicit duration(const _Rep2& _Val) 
        : _MyRep(static_cast<_Rep>(_Val)) 
    { 
    } 
         
    constexpr _Rep count() const { return (_MyRep);	} 
}; 
 
// convert duration from one unit to another. 
template<class _To, class _Rep, class _Period> inline 
constexpr typename enable_if<_Is_duration<_To>::value, _To>::type 
duration_cast(const duration<_Rep, _Period>& _Dur) 
{ 
typedef ratio_divide<_Period, typename _To::period> _CF; 
 
typedef typename _To::rep _ToRep; 
typedef typename common_type<_ToRep, _Rep, intmax_t>::type _CR; 
 
#pragma warning(push) 
#pragma warning(disable: 6326)	// Potential comparison of a constant with another constant. 
return (_CF::num == 1 && _CF::den == 1 
        ? static_cast<_To>(static_cast<_ToRep>(_Dur.count())) 
    : _CF::num != 1 && _CF::den == 1 
        ? static_cast<_To>(static_cast<_ToRep>( 
            static_cast<_CR>( 
                _Dur.count()) * static_cast<_CR>(_CF::num))) 
    : _CF::num == 1 && _CF::den != 1 
        ? static_cast<_To>(static_cast<_ToRep>( 
            static_cast<_CR>(_Dur.count()) 
                / static_cast<_CR>(_CF::den))) 
    : static_cast<_To>(static_cast<_ToRep>( 
        static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num) 
            / static_cast<_CR>(_CF::den)))); 
#pragma warning(pop) 
} 

 

duration_cast() analysis

The function duration_cast()provides the function of converting between different time units .

duration_cast()Mainly divided into two parts:

  • By ratio_dividedefined from a ratio converted to another ratio conversion ratio.
    Such as 1/10the 2/5conversion ratio is 1/4 ((1/10 / (2/5)) = 1/4) , that is to say an 1/10equivalent 1/4one 2/5.
    It corresponds to the code _CF::num = 1, _CF::den = 4.

  • Convert n units of original data to target data according to the conversion ratio (return statement). The
    returnsentence is written so complicated for efficiency and to avoid unnecessary multiplication and division. When the numerator is 1, there is no need to multiply when the denominator is 1. No need to divide.
    To simplify it (without coercion) is:
    return _Dur.count() * (_CF::num / _CF::den);

Popular speak: if Ato Bthe proportion of the conversion num/den, then 1one Acan be converted into num/dentwo Bnone Acan be converted to  n * (num/den)one B.

Note: The source code that comes with vs is really not easy to read. It is recommended to refer to the boost source code.

Predefined duration

For the convenience of writing code, vs. predefined several commonly used time units. The excerpts are as follows:

  1. typedef duration<long long, nano> nanoseconds; // 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; // 小时 

According to the above definition, we can find that the type std::chrono::microsecondsin the definition Repis long long, and the Periodtype is milli.

Note: Because the type std::chrono::microsecondsin the definition Repis long long, we cannot sleep for 100.5 milliseconds by the following method std::this_thread::sleep_for(std::chrono::microseconds(100.5));. If the type does not match, a compilation error will be reported. If we want to sleep for 100.5 milliseconds, we can write:
std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(100.5f));

Sample code

Example 1: Convert minutes to milliseconds

#include <iostream> 
#include <chrono> 
int main() 
{ 
    std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::minutes(3)); 
    std::cout << "3 minutes equals to " << ms.count() << " milliseconds\n"; 
    std::cin.get(); 
} 

Example 2. Custom unit conversion

#include <iostream> 
#include <chrono> 
 
typedef std::chrono::duration<float, std::ratio<3, 1> > three_seconds; 
typedef std::chrono::duration<float, std::ratio<1, 10> > one_tenth_seconds; 
 
int main() 
{ 
    three_seconds s = std::chrono::duration_cast<three_seconds>(one_tenth_seconds(3)); 
    std::cout << "3 [1/10 seconds] equal to " << s.count() << " [3 seconds]\n"; 
    std::cin.get(); 
} 

Example 3. Sleep for 100 milliseconds

#include <thread> 
#include <chrono> 
int main() 
{ 
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); 
    // or 
    std::this_thread::sleep_for(std::chrono::duration<long long, std::milli>(100)); 
    // or   
    // typedef ratio<1, 1000> milli; 
    std::this_thread::sleep_for(std::chrono::duration<long long, std::ratio<1, 1000> >(100)); 
} 

Reprinted: https://www.cnblogs.com/bianchengnan/p/9478638.html

Guess you like

Origin blog.csdn.net/hyl999/article/details/108006039