libreria high_resolution_clock high example c++ c++11 chrono

c++ - high_resolution_clock - ¿Cuál es la razón detrás de la falta de manipulación inmediata del conteo de ticks de std:: chrono:: duration?



chrono high resolution clock c++ example (4)

Supongamos que tenemos

#include <chrono> #include <iostream> #include <ctime> namespace Ratios { typedef std::ratio<60*60*24,1> Days; } typedef std::chrono::system_clock Clock; typedef Clock::time_point TimePoint;

Y nuestro main parece

int main(int argc, char *argv[]) { // argc check left out for brevity const Clock::rep d = static_cast<Clock::rep>(std::atoi(argv[1])); // Right now TimePoint now = Clock::now(); // Start with zero days auto days = std::chrono::duration<Clock::rep, Ratios::Days>::zero(); // Now we''d like to add d to the days days += d; // Error! days.count() = d; // Error! days = days + d; // Error! days += std::chrono::duration<Clock::rep, Ratios::Days>(d); // Okay days = days + std::chrono::duration<Clock::rep, Ratios::Days>(d); // Okay days *= d; // Why is this okay? days %= d; // And this too? TimePoint later = now + days; return 0; }

¿Cuál es la razón detrás de prohibir al usuario manipular una duration directamente?


La razón fundamental es mantener la integridad de la unidad de tiempo que representa la duration .

Puedes pensar que el rep no tiene unidad. Pero la duration es una unidad de tiempo. Uno puede sumar y restar segundos a / de segundos. Pero no se pueden agregar segundos y una cantidad sin unidades sin hacer que la expresión sea ambigua y violar el álgebra de unidades.

Dicho esto, uno puede multiplicar y dividir una unidad de tiempo por una cantidad escalar (una unidad menos), y el resultado sigue siendo una unidad de tiempo. Esta biblioteca solo representa unidades de tiempo hasta la primera potencia, o potencia cero. Una unidad de tiempo elevada a la potencia cero es un escalar y está representada por rep . Las unidades de tiempo también pueden tener un poder de 2 o más, y poderes negativos. Sin embargo, esta biblioteca no representa tales unidades.

Al sumar dos cantidades, las unidades deben ser las mismas.

Al multiplicar o dividir dos cantidades, se forma una nueva unidad (por ejemplo, km / hr). Cuando se multiplican cantidades de las mismas unidades, se agregan sus exponentes (por ejemplo, sec * sec == sec ^ 2). Cuando se dividen las cantidades de las mismas unidades, se restan sus exponentes (por ejemplo, seg./seg. == seg ^ 0 == un escalar).

La biblioteca std::chrono::duration es un subconjunto consistente de una biblioteca de cantidades físicas que maneja solo unidades de tiempo y solo aquellas unidades de tiempo con exponentes iguales a 0 y 1.


Se hace para exigirle que se adhiera a valores fuertemente tipados en lugar de valores arbitrarios.

Bjarne Stroustrup tiene ejemplos con respecto a este comportamiento en "El lenguaje de programación C ++" (4ª edición, 35.2.1, pp. 1011):

" El período es un sistema de unidades, por lo que no hay = o += tomando un valor simple. Permitir eso sería como permitir la adición de 5 de una unidad SI desconocida a una longitud en metros. Considere:

duration<long long, milli> d1{7}; // 7 milliseconds d1 += 5; // error [...]

¿Qué significaría 5 aquí? ¿5 segundos? 5 milisegundos? [...] Si sabes lo que quieres decir, sé explícito al respecto. Por ejemplo:

d1 += duration<long long, milli>{5}; //OK: milliseconds"


Supongo que esto se hace para obligarle a considerar cuáles son las unidades de la duración que desea agregar / restar. También le impide hacer suposiciones sobre las unidades en las que se encuentra el reloj.


days += d; // Error!

Esto se debe a que los days variables están en unidades de 86,400 segundos y la variable d tiene unidades. El resultado de agregar una cantidad de una unidad a un escalar sin unidad no se define en el análisis dimensional estándar.

days *= d; // Why is this okay? days %= d; // And this too?

Porque multiplicar y dividir cantidades por escalares sin unidades no tiene sentido. Multiplicando 2 segundos por 2 resultados en 4 segundos.

Considera multiplicar 2 segundos por 3 segundos; el resultado es una cantidad 6 con la unidad ''segundos al cuadrado''. Por supuesto, chrono::duration no es una biblioteca de unidades completa, por lo que no puede tener unidades como el tiempo al cuadrado, pero las bibliotecas como boost.units lo admitirán.