Chrono timer in C++ to double

家住魔仙堡 提交于 2021-02-08 10:33:21

问题


How can i create a timer that after a certain duration, it does something? so far i have been trying to use the % operation. I made a timer at the start of the function and subtracted the current time (now()function) then i % the difference by 5 because i want 5 seconds to pass:

(at the start of the program i defined start as high_resolution_clock::now())
duration<double> dur = start-high_resolution_clock::now();
if(dur%5==0)

the error ive been getting is: no operator "==" matches these operands -- operand types are: std::chrono::duration> == int


回答1:


You are looking for something like:

#include <chrono>

int main() {
    using namespace std::chrono_literals;
    using std::chrono::high_resolution_clock;
    auto start = high_resolution_clock::now();
    bool condition = true;
    while (condition) {
        auto time_passed = high_resolution_clock::now() - start;
        if( time_passed % 5s == 0s ) {
            // do your thing every 5 seconds
        }
        // ...
    }
}

Code version 1, Code version 2


Explanation

The modulo

The modulo operation for duration called with: duration % x expects x to be either of the two:

  • another duration, in which case chrono does the job for you in getting the common type of duration and x, that would allow modulo.

  • some arbitrary type, in which case the inner type of duration should be able to perform modulo with x. Which is not the case for duration that is based on <double>.

To allow modulo on duration that is based on <double> there is a need to use duration_cast or to use the first modulo option above, with another duration.

The comparison

The modulo operation returns a duration as can be seen in the reference. To compare it to an int (i.e. 0) there is a need to turn it into an int (since duration and int are not comparable) and this can be done with a call to count, e.g.:

if ( (time_passed % 5s).count() == 0 )

Alternatively we can compare it to an actual duration as we do above.


An important design note

Even though above code works and when we reach the exact modulo we will do the thing, the value the duration is counting is not in seconds, so if we just missed the 5 seconds by 2 nanos we will miss the modulo check and would not do our thing, then we will wait for the next round and would most probably miss it again. Modulo is a very bad choice for trying to catch the time, as the time that we sample jumps. A better approach would be to calculate that there has been 5 seconds or more since we last did the thing as a trigger. Which can be achieved with this code:

int main() {
    using namespace std::chrono_literals;
    using std::chrono::high_resolution_clock;
    auto start = high_resolution_clock::now();
    auto last_time_we_did_the_thing = start;
    bool condition = true;
    while (condition) {
        auto curr_time = high_resolution_clock::now();
        auto time_since_last_do_the_thing
           = curr_time - last_time_we_did_the_thing;
        if( time_since_last_do_the_thing >= 5s ) {
            // do your thing every 5 seconds
            last_time_we_did_the_thing = curr_time;
        }
        // ...
    }
}

Code ^



来源:https://stackoverflow.com/questions/60477360/chrono-timer-in-c-to-double

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!