Разница между двумя экземплярами time_point - это не продолжительность?

Я не понимаю, почему этот код задыхается от g ++ 4.7.2:

#include <chrono>

main ()
{
    std::chrono::system_clock::time_point t1, t2 ;
    std::chrono::seconds delay ;

    t1 = std::chrono::system_clock::time_point::max () ;
    t2 = std::chrono::system_clock::now () ;
    delay = t1 - t2 ;
    // t1 = t2 + delay ;
    // t1 = t2 - delay ;
}

с ошибкой:

test.cc: In function ‘int main()’:
test.cc:10:18: error: no match for ‘operator=’ in ‘delay = std::chrono::operator,<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000l> >, std::chrono::duration<long int, std::ratio<1l, 1000000l> > >((*(const std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000l> > >*)(& t1)), (*(const std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000l> > >*)(& t2)))’

Мне показалось, что «time_point - time_point» дает «продолжительность».


person pdagog    schedule 25.04.2013    source источник
comment
Ах да, верно, компиляторы C ++ все еще не справляются с сообщениями об ошибках.   -  person Konrad Rudolph    schedule 25.04.2013
comment
Авторы библиотеки @KonradRudolph могли бы значительно улучшить их за счет более либерального static_assert использования, я не уверен, почему они этого не делают.   -  person David Brown    schedule 25.04.2013
comment
@DavidBrown: нельзя использовать static_assert, чтобы сообщить, существует ли подходящая перегрузка функции / оператора. Концепции могут помочь, но их пока нет.   -  person Mike Seymour    schedule 25.04.2013
comment
@KonradRudolph, возможно, вас заинтересует камомилла github.com/SuperV1234/camomilla   -  person M310    schedule 13.06.2017


Ответы (4)


Он действительно производит продолжительность, но есть разные виды продолжительности. Шаблон std::chrono::duration основан на типе представления и соотношении единиц. std::chrono::seconds, например, имеет коэффициент 1, а std::chono::nanoseconds имеет коэффициент std::nano, или 1/1000000000. временные точки имеют одинаковые параметры шаблона.

Конкретное соотношение единиц std::chrono::system_clock::time_point определяется реализацией, но почти наверняка меньше, чем у std::chrono::seconds. Таким образом, продолжительность, полученная путем вычитания этих двух временных точек, имеет гораздо большую точность, чем может быть представлена ​​std::chrono::seconds. Поведение по умолчанию - не разрешать назначения, которые теряют точность с длительностями, которые имеют целочисленные представления. Таким образом, вы можете либо использовать длительность с достаточной точностью (std::chrono::system_clock::duration), либо привести результат к желаемой длительности (std::chrono::duration_cast<std::chrono::seconds>(...)).

person David Brown    schedule 25.04.2013
comment
Большое спасибо за ваш ответ. Итак, если бы я использовал тип std :: chrono :: nanoseconds для переменной задержки, я бы не заметил проблемы и не узнал бы важную вещь! - person pdagog; 26.04.2013
comment
@pdagog std::chrono::nanoseconds не обязательно будет работать (по крайней мере, не везде). std::chrono::system_clock::time_point может быть в наносекундах или может быть еще меньше. Вот почему вам следует использовать std::chrono::system_clock::duration. - person David Brown; 26.04.2013
comment
Конечно: я должен был сказать. Итак, если бы я использовал тип std :: chrono :: nanoseconds для переменной задержки, которая выглядит как зернистость тактовой частоты в моей системе, я бы не заметил. ... Спасибо за точность. - person pdagog; 26.04.2013

time_point - time_point действительно возвращает duration, но не тот, который указан в коде. Вы можете заменить std::chrono::seconds на std::chrono::system_clock::duration или использовать duration_cast для преобразования в нужный вам вид.

person Pete Becker    schedule 25.04.2013

Разница между двумя временными точками - это действительно продолжительность; но вы не можете неявно преобразовать один тип продолжительности в другой, так как это может незаметно потерять точность.

Если вы хотите уменьшить точность с system_clock::duration до seconds, вам нужно сделать преобразование явным, используя duration_cast:

delay = duration_cast<std::chrono::seconds>(t1 - t2);

В качестве альтернативы вы можете захотеть сохранить точность системных часов:

auto delay = t1 - t2; // Probably microseconds, or nanoseconds, or something
person Mike Seymour    schedule 25.04.2013

Компилятор не позволяет преобразовывать длительность в целое число, если есть вероятность, что результатом преобразования будет действительное число. Вы используете тип std::chrono::seconds, который определяется как duration<*at least 35 bits integer*, ratio<1> >. Попробуйте вместо этого использовать продолжительность с плавающей запятой:

duration<double, 1> delay; // or duration<double> delay;
delay = t1 - t2;

или некоторый duration_cast, как упоминалось другими.

person Viktor Plaček    schedule 23.09.2020