Как создать собственные хронометры

Я создаю элемент управления пользовательского интерфейса временной шкалы, и время на этой временной шкале всегда начинается с нуля, как секундомер. Я подумал об использовании std::chrono::steady_clock, чтобы сохранить время начала и окончания на шкале, однако мне кажется неправильным указывать здесь время по часам, например, «10:00 марта 2017 года» не имеет ничего общего с началом шкала.

Должен ли я / могу ли я создать собственные часы, которые начинают время с «0»?


person Jan Wilmans    schedule 05.03.2017    source источник
comment
Вы можете создать собственные часы, которые начинаются с 0. Трудно сказать, следует ли вам это делать, потому что я не знаю, как будут использоваться ваши time_points. Должны ли они быть стабильными при выполнении программы или экспортироваться/импортироваться в другие процессы? Нужна ли им наносекундная точность? Вторая точность? Точность минут? Будет ли достаточно просто сохранить now() из существующих часов и вычесть это из будущего времени? У вас есть примеры использования кода, которые вы можете нам показать?   -  person Howard Hinnant    schedule 14.03.2017
comment
Спасибо, что ответили, Говард, мне нравятся твои разговоры о cppcon chrono, кстати. Хранение устойчивой_часов time_point мне бы подошло. Чтобы ответить на ваши вопросы, time_points являются внутренними для процесса, поэтому не беспокойтесь, но мне нужна точность в наносекундах.   -  person Jan Wilmans    schedule 15.03.2017
comment
Думаю, я просто буду использовать обычный stead_clock. Из интереса, как я могу определить тип, похожий на устойчивый_час, но с эпохой в 0? Хочу поэкспериментировать :)   -  person Jan Wilmans    schedule 15.03.2017


Ответы (1)


Вот пример пользовательских хроночасов, основанных на steady_clock и отсчитывающих время с момента первого вызова (приблизительно):

#include "chrono_io.h"
#include <chrono>
#include <iostream>

struct MyClock
{
    using duration   = std::chrono::steady_clock::duration;
    using rep        = duration::rep;
    using period     = duration::period;
    using time_point = std::chrono::time_point<MyClock>;
    static constexpr bool is_steady = true;

    static time_point now() noexcept
    {
        using namespace std::chrono;
        static auto epoch = steady_clock::now();
        return time_point{steady_clock::now() - epoch};
    }
};

int
main()
{
    using namespace date;
    std::cout << MyClock::now().time_since_epoch() << '\n';
    std::cout << MyClock::now().time_since_epoch() << '\n';
    std::cout << MyClock::now().time_since_epoch() << '\n';
    std::cout << MyClock::now().time_since_epoch() << '\n';
}

Нужно просто определить вложенные типы duration, rep и period, которые он может просто украсть из steady_clock, а затем создать свой собственный time_point. Не следует использовать time_point steady_clock, потому что эпохи MyClock и steady_clock различны, и вы не хотите случайно смешать эти два time_point в арифметике.

Поскольку MyClock основано на steady_clock, это is_steady.

И функция now() сохраняет текущее время epoch в static (оценивается при первом вызове), а затем просто находит время с epoch при каждом вызове. Это вычитание создает duration, который можно использовать для построения MyClock::time_point.

Я использую "chrono_io.h" только потому, что мне лень форматировать. Вам не нужен этот заголовок для создания собственных часов. Это ничего не делает, но упрощает распечатку длительности.

Эта программа просто выводит для меня:

1618ns
82680ns
86277ns
88425ns
person Howard Hinnant    schedule 15.03.2017