Часы с переопределенными time_point
и duration
, которые не соответствуют period
, известным во время компиляции, не соответствуют Clock
требованиям, как объяснил Говард Хиннант.
Использование класс, эмулирующий арифметику c типа для скрытия дополнительных деталей реализации, не работает.
В стандарте не определено, что это за эмуляция , возможность использования эмуляции Тип доступен только для часов, предусмотренных стандартной реализацией. В качестве практического доказательства std::chrono
и boost::chrono
не работают хорошо с boost::rational
.
Однако общая задача избегать разделения на каждый раз, когда запрос имеет как минимум два практических решения.
Первое решение состоит в том, чтобы следовать намерению отложить деление до необходимого, но не переопределять time_point
и duration
. Определите стандартные часы и, как расширение, определите интерфейс для необработанной метки времени. Таким образом, часы могут иметь метод raw_now()
, возвращающий тип raw_time_point
, разница такого типа raw_duration
. raw_time_point
может быть неявно преобразовано в time_point
и raw_duration
в duration
.
Вторым решением является вычисление стандартного time_point
для каждого запроса времени, но используйте libdivide библиотека, которая выполняет быстрое деление без операции деления.
Библиотека берет делитель и обрабатывает его так, что каждое деление с использованием обработанного делителя выполняется с использованием быстрых операций. Конечно, для обработки делителя требуется время, но для повторного деления с одним и тем же делителем это одноразовые накладные расходы. Так что эта библиотека выглядит идеально подходящей для этой задачи. (Обратите внимание, что библиотека бесполезна для констант, известных во время компиляции, так как в этом случае компилятор избегает деления сам по себе, но QueryPerformanceFrequency
результатом является постоянная времени выполнения).