У меня есть следующий класс Timer, чтобы упростить получение времени, прошедшего с эпохи:
#include <chrono>
class Timer {
public:
void start(void);
template <typename duration_type>
const duration_type time_elapsed(void);
private:
std::chrono::high_resolution_clock::time_point epoch;
};
void Timer::start(void) {
epoch = std::chrono::high_resolution_clock::now();
}
template <typename duration_type>
const duration_type Timer::time_elapsed(void) {
return std::chrono::duration_cast<duration_type>(std::chrono::high_resolution_clock::now() - epoch);
}
int main(void) {
Timer timer;
timer.start();
// pointless loop to cause a delay
for (int x = 1; x < 1000000; ++x) {
x * x * x;
}
std::chrono::nanoseconds elapsed = timer.time_elapsed<std::chrono::nanoseconds>();
std::cout << elapsed.count() << std::endl;
return 0;
}
У меня такое чувство, что я слишком усложняю свой класс, делая Timer :: time_elapsed () шаблонной функцией и в идеале хотел бы упростить ее использование до следующего:
std::chrono::nanoseconds elapsed = timer.time_elapsed();
std::cout << elapsed.count() << std::endl;
Я исправил несколько вещей в вашем коде и добавил правильное использование std::chrono
, Список изменений включает в себя:
(void)
аргументы от вызовов функций, потому что это не совсем так, как в C ++ 🙂return 0;
от main()
это не нужно в C ++, потому что компилятор сделает это за вас.typedef
рефакторинг может быть проще в будущем.std::chrono
также используется в поточной библиотеке.inline
простота ключевого слова в реализации вне класса.time_elapsed()
метод const
const
из возвращаемого значения time_elapsed()
метод и добавил его с другой стороны в использовании этого метода, потому что в этом точном месте const
достаточно.time_elapsed()
способ вернуть собственное разрешение часов в return
, Это гораздо лучшее решение, потому что здесь вы никогда не потеряете данные. Возможно, вы захотите потерять его при предоставлении данных пользователю в определенном блоке (то есть нас). Вы должны использовать duration_cast
чтобы сообщить компилятору, что вы согласны потерять некоторые данные, и нам достаточно разрешения.Надеюсь, что приведенный ниже код и вышеуказанные изменения будут вам интересны.
#include <chrono>
#include <thread>
#include <iostream>
using namespace std::chrono;
class Timer {
public:
typedef high_resolution_clock Clock;
void start()
{ epoch = Clock::now(); }
Clock::duration time_elapsed() const
{ return Clock::now() - epoch; }
private:
Clock::time_point epoch;
};
int main() {
Timer timer;
timer.start();
// sleep some time
std::this_thread::sleep_for(microseconds(40));
const auto elapsed = timer.time_elapsed();
std::cout << duration_cast<microseconds>(elapsed).count() << "us" << std::endl;
}
Кстати, я не хотел играть с интерфейсом класса (я уже сделал слишком много изменений). Если вы еще не связаны с этим интерфейсом, я рекомендую использовать тот, который предложил @sehe. Но не используйте это double
в качестве возвращаемого значения 😉
Возвращает вспомогательный класс, который хранит now-epoch () и выполняет высокоточное приведение к оператору T с истекшего времени. Или есть time_elapsed_in_units<T>
метод, который выглядит как прошедшее время, а затем прошедшее время возвращает структуру, которая вызывает единицы в операторе T.
Перегрузка оператора вспомогательного класса T позволяет вам определить, какой тип вызывается неявно.