Эй, ребята, пытаюсь вычесть длительность из времени, используя std :: chrono, что я путаю?

#c #time #chrono

#c #время #хроно

Вопрос:

Итак, мой код не компилируется, но мне бы очень этого хотелось. Вот мой код:

 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. Пожалуйста, добавьте текст сообщения об ошибке.

2. std::chrono::steady_clock::now() это не a std::chrono::steady_clock , это a std::chrono::time_point , поэтому я бы предположил, что задание в строке 2 не выполняется.

3. @NathanPierson Строка 2 была опечаткой с моей стороны при переносе кода, это не сбой там, это сбой при вычитании на месте, как я уже сказал. Я добавил сообщение об ошибке, которое поддерживает это.

Ответ №1:

Ссылка Ссылка на код

Проблемы

  1. Как указано в комментариях, в строке 2 возвращаемый тип std::chrono::steady_clock::now() is std::chrono_time_point .
  2. 2-й аргумент шаблона, предоставленный для std::chrono::duration , не соответствует указанным требованиям. Например, вы заметите ошибку компиляции static assertion failed: period must be a specialization of ratio , соответствующую этой строке.
  3. Наконец, оператор не найден, потому что нет соответствующего -= оператора для предоставленных неподдерживаемых аргументов шаблона.

Решение

  • Вы можете использовать std::ratio<1,1> для представления секунд.
 auto duration = std::chrono::duration<std::int64_t, std::ratio<1,1>>(numSeconds);
 // or simply std::chrono::seconds(numSeconds)
 
  • Попытка использовать тип с плавающей запятой для представления времени может быть не очень хорошей идеей (почему?). Лучше использовать меньшую единицу измерения (например, миллисекунды вместо секунд), или, если вы настаиваете на типе с плавающей запятой, вам понадобится больший тип, например. double(связанная документация объясняет это). Что-то вроде этого, похоже, заставляет ваш пример работать.
 double numSeconds = 50.0;
using FpDurationT = std::chrono::duration<double, std::ratio<1,1>>;
using TimepointT = std::chrono::time_point<std::chrono::steady_clock, FpDurationT>;
TimepointT startTime = std::chrono::steady_clock::now();
auto duration = FpDurationT(numSeconds);
startTime -= duration;
 

Комментарии:

1. Почему мои аргументы шаблона не поддерживаются? У меня есть количество секунд, которое мне нужно указать как float, а не как int. Кроме того, я думал, что std::chrono::seconds был допустимым вторым параметром? Я не получаю никаких предупреждений при определении самой продолжительности.

2. Отредактировано выше, чтобы ответить на первую половину вашего вопроса. Что касается 2-го, нет, std::chrono::seconds это псевдоним для std::chrono::duration<integral type, std::ratio<1,1>> — Эти требования / определения четко указаны в связанной документации.