Таймер хронографа в C ++ для удвоения - PullRequest
0 голосов
/ 01 марта 2020

Как я могу создать таймер, который после определенной продолжительности что-то делает? до сих пор я пытался использовать операцию%. Я запустил таймер в начале функции и вычитал текущее время (функция now ()), затем я% от разницы на 5, потому что я хочу, чтобы прошло 5 секунд:

(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)

ошибка, которую я получал is: ни один оператор "==" не соответствует этим операндам - ​​типы операндов: std :: chrono :: duration> == int

1 Ответ

3 голосов
/ 01 марта 2020

Вы ищете что-то вроде:

#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
        }
        // ...
    }
}

Версия кода 1 , Версия кода 2


Пояснение

по модулю

Операция по модулю для длительности , вызываемая с помощью: duration % x, ожидает, что x будет одним из двух:

  • другая длительность , и в этом случае chrono выполняет за вас работу по получению общего типа duration и x, что позволило бы по модулю .

  • некоторый произвольный тип , в этом случае внутренний тип duration должен иметь возможность выполнять по модулю x. Это не относится к duration, основанному на <double>.

Чтобы разрешить по модулю duration, основанный на <double>, необходимо использовать duration_cast или использовать первый параметр по модулю, описанный выше, с другим duration.

Сравнение

Операция по модулю возвращает duration, как видно из ссылка. Чтобы сравнить его с int (т.е. 0), необходимо превратить его в int (поскольку duration и int не сопоставимы), и это можно сделать с помощью вызова count, например:

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

В качестве альтернативы мы можем сравнить ее с фактической продолжительностью, как мы делаем выше.


Важное примечание к дизайну

Даже если приведенный выше код работает и когда мы Достигнув точного значения по модулю, мы это сделаем, значение, которое подсчитывает duration, не в секундах, поэтому, если мы просто пропустили 5 секунд на 2 нано, мы пропустим проверку по модулю и не сделаем свое дело, тогда мы будем дождитесь следующего раунда и скорее всего пропустите его снова. Modulo - очень плохой выбор для того, чтобы попытаться поймать время, поскольку время, которое мы пробуем прыгать. Лучшим подходом было бы рассчитать, что прошло 5 или более секунд с тех пор, как мы в последний раз делали это как триггер. Что может быть достигнуто с помощью этого кода:

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;
        }
        // ...
    }
}

Код ^

...