#c #time #duration #chrono
#c #время #Продолжительность #chrono
Вопрос:
Я задал этот вопрос вчера, но мой поток был закрыт, поэтому я говорю в пустоту. Итак, мой код не компилируется, но я бы очень этого хотел. Вот мой фрагмент:
float numSeconds = 50;
std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
auto duration = std::chrono::duration<float, std::chrono::seconds>(numSeconds);
startTime -= duration;
Похоже, это должно быть довольно просто, но я получаю ошибку operator not found при попытке вычитания на месте. Есть предложения? Я также попытался заменить третью строку следующим:
auto duration = std::chrono::duration<float, std::ratio<1, 1>>(numSeconds);
Однако эта строка, похоже, не является причиной проблем, оба подхода кажутся допустимыми. Это моя последняя строка, которая все еще недовольна. Код ошибки, который я получаю, это:
"Error C2679 binary '-=': no operator found which takes a right-hand operand of type 'std::chrono::duration<float,std::chrono::seconds>' (or there is no acceptable conversion)"
Кроме того, когда я меняю последнюю строку на:
timer.m_startTime = timer.m_startTime - duration;
Я получаю следующий код ошибки:
Error C2679 binary '=': no operator found which takes a right-hand operand of type 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<float,std::ratio<1,1000000000>>>' (or there is no acceptable conversion)
Это как-то несовместимые типы? Я бы подумал, что они разрешат одно и то же.
Комментарии:
1. Не знаю всех подробностей. Указанная вами продолжительность, похоже, имеет другой тип, чем значение по умолчанию для steady clock . Должен быть тип
std::chrono::steady_clock::duration
.2. Так кажется! Однако,
std::chrono::steady_clock::duration<float, std::ratio<1, 1>>
похоже, это не правильный способ инициализации длительности, поэтому я не уверен, как получить правильный тип длительности из числа секунд с плавающей запятой.3. Я думаю, проблема в том, что вы пытаетесь установить / изменить аргументы шаблона, что приводит к несовместимому типу. Но в любом случае, в настоящее время я не могу вам помочь.
4. Возможно, я думаю, что мне просто понадобилось явное приведение. Попытка
auto duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>( std::chrono::duration<float, std::ratio<1, 1>>(seconds));
может быть ошибкой, поскольку она компилируется. Я добавлю это в качестве ответа, если он действительно поступает правильно.
Ответ №1:
float numSeconds = 50;
Следующая строка:
std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
можно было бы более кратко записать как:
auto startTime = std::chrono::steady_clock::now();
Оба синтаксиса эквивалентны и верны.
Причина, по которой это не компилируется:
auto duration = std::chrono::duration<float, std::chrono::seconds>(numSeconds);
заключается в том, что второй аргумент шаблона duration
принимает a std::ratio
, а не a std::chrono::duration
. Правильный способ сказать это:
auto duration = std::chrono::duration<float, std::ratio<1, 1>>(numSeconds);
Вышеуказанное означает, что duration
тип std::chrono::duration
имеет представление float
и период в 1/1 секунды. Это означает, что это всего лишь количество секунд с плавающей запятой.
Второй параметр шаблона std::ratio
по умолчанию равен 1, поэтому приведенное выше можно упростить до:
auto duration = std::chrono::duration<float, std::ratio<1>>(numSeconds);
И второй параметр шаблона std::chrono::duration
по умолчанию std::ratio<1>
имеет значение, поэтому вышесказанное можно упростить до:
auto duration = std::chrono::duration<float>(numSeconds);
Следующее не компилируется:
startTime -= duration;
потому chrono
что есть правило, согласно которому значения с представлением с плавающей запятой никогда не преобразуются неявно в значения с целочисленным представлением. Это делается для того, чтобы избежать ошибки усечения, возникающей при присвоении a float
значению an int
.
Есть несколько способов исправить это. Например, вы могли бы сохранить результат в a float
-based time_point
:
auto anotherTime = startTime - duration;
anotherTime
имеет тип std::chrono::time_point<std::chrono::steady_clock, std::chrono::duration<float, std::chrono::steady_clock::period>>
.
Или вы можете явно привести duration
обратно к целочисленному типу:
startTime -= std::chrono::duration_cast<std::chrono::seconds>(duration);
Если вы выберете последнее, тогда вообще нет смысла использовать float
. И вся последовательность может выглядеть так:
using namespace std::chrono_literals;
auto startTime = std::chrono::steady_clock::now();
auto duration = 50s;
startTime -= duration;
или:
using namespace std::chrono_literals;
auto startTime = std::chrono::steady_clock::now();
startTime -= 50s;
или:
using namespace std::chrono_literals;
auto startTime = std::chrono::steady_clock::now() - 50s;
Вот 1-часовой видеоурок <chrono>
, который может оказаться полезным для вас: https://www.youtube.com/watch?v=P32hvk8b13M
Комментарии:
1. Спасибо, Говард, это невероятно тщательно! Я думаю, что about охватывает все вопросы, которые у меня могли возникнуть.