Анализ, который вы провели в своем вопросе, в основном верен. И есть несколько хороших способов сделать эту работу. 1 , 2
Использование auto
// now
system_clock::time_point now = system_clock::now();
// duration
duration<float> duration(1.0f / 60.0f); // float in seconds
// now + duration
auto futureTime = now + duration;
Тип futureTime
является time_point<system_clock, duration<float, nano>>
. То есть это time_point
на основе system_clock
, в котором хранится nanoseconds
, представленный float
.
Этот тип может использоваться с std::condition_variable::wait_until
.
Cast now + duration
назад к system_clock::time_point
:
// now
system_clock::time_point now = system_clock::now();
// duration
duration<float> duration(1.0f / 60.0f); // float in seconds
// now + duration
system_clock::time_point futureTime =
time_point_cast<system_clock::duration>(now + duration);
time_point_cast<duration>
- как вы разыгрываете time_point
с. Вы должны явно указать тип длительности, которую вы хотите получить в результате time_point
. Результирующий time_point
будет по-прежнему основываться на тех же часах.
Результат будет усечен (округлен до нуля) до следующего целого числа system_clock::duration
(nanoseconds
на этой платформе).
Этот тип может использоваться с std::condition_variable::wait_until
.
Вокруг now + duration
назад к system_clock::time_point
:
system_clock::time_point futureTime = round<system_clock::duration>(now + duration);
Это похоже на предыдущее решение, за исключением округления до ближайшего интеграла nanoseconds
и до четного nanoseconds
на ничью. std::chrono::round
доступно в C ++ 17 и более поздних версиях. Это даст результат не более 1ns
, отличный от time_point_cast
.
Если у вас нет C ++ 17, но вы все еще хотите использовать round
, не стесняйтесь использовать этот .
Этот тип может использоваться с std::condition_variable::wait_until
.
Представляет 1/60 в точности с интегральной арифметикой
// now
system_clock::time_point now = system_clock::now();
// duration
duration<int, std::ratio<1, 60>> duration{1}; // 1/60 of a second
// now + duration
auto futureTime = now + duration;
Обычно люди говорят:
Невозможно точно представить 1 / 60 секунду.
Но вы можете с <chrono>
. :-) duration<int, std::ratio<1, 60>>
считает в единицах 1 / 60 секунды, используя представление int
. duration{1}
равно 1 / 60 секунды. duration{2}
составляет 2 / 60 секунды. И т.д.
auto
действительно пригодится здесь. Тип futureTime
: time_point<system_clock, duration<system_clock::rep, ratio<1, 3'000'000'000>>>
. Или по-английски: A time_point
на основе system_clock
с использованием продолжительности с типом представления, который system_clock::time_point
использует (обычно long long
), и периодом 1 / 3 nanoseconds
.
Оказывается, что 1 / 3 nanoseconds
- это грубая точность, которая может точно представлять оба system_clock::period
( nanoseconds
на этой платформе) и 1 / 60 секунды.
И <chrono>
вычисляет все это автоматически. Все, что вам нужно сделать, чтобы воспользоваться этим - использовать auto
.
Этот тип может использоваться с std::condition_variable::wait_until
.
Можно также использовать duration<int, std::ratio<1, 60>>
в сочетании с time_point_cast
или round
, как показано ранее, если вы хотите вернуться к system_clock::time_point
.
на основе наносекунд.
Резюме
Что лучше? Вы должны будете решить это на основе других факторов в вашем приложении. Обычно лучше всего то, что делает остальную часть вашего кода более читабельной.
Но у вас есть варианты, и все они хорошие варианты. И все они будут работать с std::condition_variable::wait_until
.
Когда вы изучаете свои варианты, если он не компилируется, это потому, что <chrono>
перехватывает ваши ошибки во время компиляции (как и первый). Если он компилируется (и если вы не избежали системы типов с .count()
или .time_since_epoch()
), то он работает.
1 Ответы в этом вопросе предполагают, что system_clock::duration
равно nanoseconds
, как указано в вопросе. Это верно только для gcc и отличается в Windows и macOS.
2 Чтобы не потеряться в многословии, я пишу свои ответы, как будто есть:
using namespace std::chrono;
в игре. Это делает вещи , поэтому намного более читабельными.