Привести chrono::milliseconds к uint64_t?

Предполагая, что у меня есть количество миллисекунд в переменной x:

chrono::milliseconds x = std::chrono::duration_cast<chrono::milliseconds>(something);

как преобразовать x из chrono::milliseconds в uint64_t?

Я пытался:

uint64_t num = std::chrono::duration_cast<uint64_t>(x);

но он говорит:

нет соответствующей функции для вызова duration_cast(std::chrono::milliseconds&)


person user997112    schedule 10.03.2015    source источник
comment
Будет ли std::chrono::duration::count делать то, что вы хотите? en.cppreference.com/w/cpp/chrono/duration/count   -  person paco_uk    schedule 10.03.2015
comment
ага, похоже может!   -  person user997112    schedule 10.03.2015


Ответы (2)


Прежде всего, вы вообще не должны делать такого рода вещи. <chrono> предоставляет типобезопасную и универсальную библиотеку единиц измерения для обработки продолжительности времени, и есть несколько веских причин избегать этой безопасности и универсальности.

Некоторые примеры проблем, которые не случаются с типобезопасной универсальной библиотекой модулей и случаются с небезопасными целочисленными типами:

// a type-safe units library prevents these mistakes:
int seconds = ...
int microseconds = seconds * 1000; // whoops
int time = seconds + microseconds; // whoops

void bar(int seconds);

bar(microseconds); // whoops

// a generic duration type prevents the need for:
unsigned sleep(unsigned seconds);
int usleep(useconds_t useconds);
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

int attosleep(long long attoseconds); // ???

// just use:
template<typename Duration>
int sleep_for(Duration t); // users can specify sleep in terms of hours, seconds, microseconds, femetoseconds, whatever. Actual sleep duration depends on QoI, as always.

Примером веской причины может быть совместимость со сторонней библиотекой, которая приняла неудачное решение не использовать типобезопасную универсальную библиотеку модулей в своем API. В этом случае преобразования должны выполняться как можно ближе к границе API, чтобы свести к минимуму степень использования небезопасных типов.


Итак, с учетом сказанного, когда у вас есть веская причина, вы делаете это следующим образом:

std::chrono::milliseconds x = ...
std::uint64_t num = x.count();

Имейте в виду, что предопределенные длительности хронографа, такие как chrono::milliseconds, используют представления со знаком, поэтому вам нужно позаботиться о том, чтобы значение подходило для преобразования в uint64_t.

person bames53    schedule 10.03.2015
comment
Будет ли duration_cast обрабатывать беззнаковое приведение к uint64_t? - person user997112; 10.03.2015
comment
@user997112 user997112 Он будет выполнять приведение, но не будет делать ничего особенного для защиты от ошибок переполнения или приведения отрицательных значений к большим значениям без знака. - person bames53; 10.03.2015

Прототип для std::chrono::duration_cast:

template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);

Вы не можете получить uint64_t напрямую, потому что он преобразует длительность (duration_cast). Итак, вам нужно создать std::duration с std::uint64_t.

using cast = std::chrono::duration<std::uint64_t>;
std::uint64_t ticks = std::chrono::duration_cast< cast >(something).count();
person edmz    schedule 10.03.2015