[Original] C ++ nuevo estándar std :: chrono :: duration
Relación de duración del crono de C ++ 11 del resumen original
Visión de conjunto
El nuevo estándar C ++ proporciona una nueva biblioteca de subprocesos. Recientemente, al escribir código de prueba, debe poner el subproceso actual en suspensión. Simplemente llame al Sleep () proporcionado por Windows directamente . En el nuevo estándar, puede usar std :: this_thread :: sleep_for () O std :: this_thread :: sleep_until ()
para lograr dormir. Lo que implica std :: chrono :: duration y std :: chrono :: time_point . Este artículo solo resume std :: chrono :: duration , std :: chrono :: time_point escribirá otro resumen.
std :: chrono :: duración
descripción
std :: chrono :: duration se define en el archivo y se utiliza para representar un período de tiempo.
Las palabras originales en cppreference son las siguientes:
La plantilla de clase std :: chrono :: duration representa un intervalo de tiempo.
Consiste en un recuento de tics de tipo Rep y un período de tick, donde el período de tick es una constante racional en tiempo de compilación que representa el número de segundos de un tick al siguiente.
Los únicos datos almacenados en una duración es un recuento de ticks de tipo Rep. Si Rep es un punto flotante, entonces la duración puede representar fracciones de ticks. El período se incluye como parte del tipo de duración y solo se usa al convertir entre diferentes duraciones.
Rep
El parámetro representa el tipo de unidad de tiempo que se puede pasar , que puede ser float, int, int64, etc. Si es un float, significa que se puede pasar una parte de la unidad de tiempo . Por ejemplo, pasar 1,2 significa 1,2 veces la unidad de tiempo . Period
El parámetro representa la unidad de tiempo , que puede ser microsegundos, milisegundos, segundos, minutos, horas, etc. (u otras unidades personalizadas, el tipo es std :: ratio ).
Nota:
- La marca mencionada anteriormente puede entenderse como un período o una unidad de tiempo.
- El número de segundos indica que el valor del período se calcula en función de los segundos.
Definición de clase
std :: chrono :: duration es una clase de plantilla. El código clave se extrae de la siguiente manera (el formato ha sido ajustado):
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)
}
análisis de duration_cast ()
La función duration_cast()
proporciona la función de convertir entre diferentes unidades de tiempo .
duration_cast()
Principalmente dividido en dos partes:
-
Por
ratio_divide
definido a partir de una relación convertida a otra relación de conversión.
Tales como1/10
la2/5
relación de conversión es1/4
((1/10 / (2/5)) = 1/4) , es decir un1/10
equivalente1/4
uno2/5
.
Corresponde al código_CF::num = 1, _CF::den = 4
. -
Convierta los datos originales de n unidades en los datos de destino de acuerdo con la tasa de conversión (declaración de retorno). La
return
oración está escrita tan complicada para la eficiencia y evitar multiplicaciones y divisiones innecesarias. Cuando el numerador es 1, no hay necesidad de multiplicar cuando el el denominador es 1. No es necesario dividir.
Para simplificarlo (sin coerción) es:return _Dur.count() * (_CF::num / _CF::den);
Habla popular: si A
a B
la proporción de la conversión num/den
, entonces 1
uno A
se puede convertir en num/den
dos B
, n
uno A
se puede convertir en n * (num/den)
uno B
.
Nota: El código fuente que viene con vs no es realmente fácil de leer. Se recomienda consultar el código fuente de boost.
Duración predefinida
Para la conveniencia de escribir código, frente a varias unidades de tiempo de uso común predefinidas. Los extractos son los siguientes:
- typedef duration <long long, nano> nanosegundos; // nanosegundos
- typedef duration <long long, micro> microsegundos; // 微秒
- typedef duration <long long, milli> milisegundos; // 毫秒
- typedef duration <long long> segundos; // 秒
- typedef duration <int, ratio <60>> minutos; // 分钟
- typedef duration <int, ratio <3600>> horas; // 小时
De acuerdo con la definición anterior, podemos encontrar que el tipo std::chrono::microseconds
en la definición Rep
es long long
, y el Period
tipo es milli
.
Nota: Debido a que el tipo
std::chrono::microseconds
en la definiciónRep
eslong long
, no podemos dormir durante 100,5 milisegundos con el siguiente métodostd::this_thread::sleep_for(std::chrono::microseconds(100.5));
. Si el tipo no coincide, se informará un error de compilación. Si queremos dormir durante 100,5 milisegundos, podemos escribir:std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(100.5f));
Código de muestra
Ejemplo 1: convertir minutos en milisegundos
#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();
}
Ejemplo 2. Conversión de unidades personalizadas
#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();
}
Ejemplo 3. Dormir durante 100 milisegundos
#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));
}
Reimpreso: https://www.cnblogs.com/bianchengnan/p/9478638.html