2015-03-10 4 views
1

Предполагая, что я количество миллисекунд в переменной x:Cast chrono :: миллисекунды до uint64_t?

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 (СТД :: хроно :: миллисекунды &)

+2

Был ли std :: chrono :: duration :: count делать то, что вы хотите? http://en.cppreference.com/w/cpp/chrono/duration/count –

+0

ah ha, похоже, что это возможно! – user997112

ответ

3

Первый из всего, вы, как правило, не должны делать такого рода вещи. <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.

+0

Будет ли long_cast обрабатывать неподписанное приведение к uint64_t? – user997112

+0

@ user997112 Он будет делать приведение, но он не будет делать ничего особенного, чтобы защитить от ошибок переполнения или отбрасывать отрицательные значения на большие значения без знака. – bames53

1

Прототип 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();