4

Assuming I have the number of milliseconds in variable x:

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

how do I convert x from chrono::milliseconds to uint64_t?

I have tried:

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

but it says:

no matching function for call to duration_cast(std::chrono::milliseconds&)

zahir
  • 1,298
  • 2
  • 15
  • 35
user997112
  • 29,025
  • 43
  • 182
  • 361

2 Answers2

4

First of all, you generally shouldn't do this sort of thing. <chrono> provides a type-safe and generic units library for handling time durations, and there are few good reasons to escape this safety and genericity.

Some examples of the ills that don't happen with a type-safe, generic units library and which do happen with type-unsafe integral types:

// 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.

An example of a good reason would be compatibility with a third party library that made the unfortunate decision not to use a type-safe, generic units library in their API. In this case the conversions should be done as close as possible to the API boundary in order to minimize the extent to which unsafe types are used.


So with that said, when you do have a good reason, you do so like this:

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

Keep in mind that the predefined chrono durations such as chrono::milliseconds use signed representations, so you'll need to take care to ensure the value is appropriate for conversion to uint64_t.

bames53
  • 86,085
  • 15
  • 179
  • 244
  • Would duration_cast handle the unsigned cast to uint64_t? – user997112 Mar 10 '15 at 16:16
  • @user997112 It would do the cast, but it won't do anything special to protect from overflow errors, or casting negative values to large unsigned values. – bames53 Mar 10 '15 at 17:37
3

The prototype for std::chrono::duration_cast is:

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

You can't get an uint64_t directly, because it converts durations (duration_cast). So you need to create a std::duration with std::uint64_t.

using cast = std::chrono::duration<std::uint64_t>;
std::uint64_t ticks = std::chrono::duration_cast< cast >(something).count();
edmz
  • 8,220
  • 2
  • 26
  • 45