Reputation: 9240
I'm using c++11 <chrono>
and have a number of seconds represented as a double. I want to use c++11 to sleep for this duration, but I cannot fathom how to convert it to a std::chrono::duration
object that std::this_thread::sleep_for
requires.
const double timeToSleep = GetTimeToSleep();
std::this_thread::sleep_for(std::chrono::seconds(timeToSleep)); // cannot convert from double to seconds
I've locked at the <chrono>
reference but I find it rather confusing.
Thanks
EDIT:
The following gives error:
std::chrono::duration<double> duration(timeToSleep );
std::this_thread::sleep_for(duration);
the error:
c:\program files (x86)\microsoft visual studio 11.0\vc\include\chrono(749): error C2679: binary '+=' : no operator found which takes a right-hand operand of type 'const std::chrono::duration<double,std::ratio<0x01,0x01>>' (or there is no acceptable conversion)
2> c:\program files (x86)\microsoft visual studio 11.0\vc\include\chrono(166): could be 'std::chrono::duration<__int64,std::nano> &std::chrono::duration<__int64,std::nano>::operator +=(const std::chrono::duration<__int64,std::nano> &)'
2> while trying to match the argument list '(std::chrono::nanoseconds, const std::chrono::duration<double,std::ratio<0x01,0x01>>)'
2> c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(164) : see reference to function template instantiation 'xtime std::_To_xtime<double,std::ratio<0x01,0x01>>(const std::chrono::duration<double,std::ratio<0x01,0x01>> &)' being compiled
2> c:\users\johan\desktop\svn\jonsengine\jonsengine\src\window\glfw\glfwwindow.cpp(73) : see reference to function template instantiation 'void std::this_thread::sleep_for<double,std::ratio<0x01,0x01>>(const std::chrono::duration<double,std::ratio<0x01,0x01>> &)' being compiled
Upvotes: 49
Views: 55770
Reputation: 3423
Note that duration
s second template argument defaults to std::ratio<1>
so you get seconds by default
template <class _Rep, class _Period = ratio<1>>
class duration;
using milliseconds = duration<long long, milli>;
using seconds = duration<long long>;
using minutes = duration<int, ratio<60>>;
using hours = duration<int, ratio<3600>>;
First create a std::chrono::duration<double>
and then cast it to you desired period.
double seconds;
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>
(
std::chrono::duration<double>{ seconds }
);
Upvotes: 2
Reputation: 511
None of the above worked for me. The working solution was found as an answer to a different question:
Terse conversion from double seconds to std::chrono::steady_clock::duration?
double period_in_seconds = 3.4;
auto as_duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(period_in_seconds));
This converts a double
to a std::chrono::steady_clock::duration
.
In general, when working with a standard clock, such as steady_clock
, your duration variables should always be of that clock's member type, such as std::chrono::steady_clock::duration
.
Avoid creating your own duration types from the template, such as std::chrono::duration<double>
, except for temporary use with duration_cast
as shown above.
This makes time comparisons against std::chrono::steady_clock::now()
fastest, as it avoids needless conversion at runtime, as the duration type of your variables will already match the duration type of the time_point
returned by now()
.
Upvotes: 6
Reputation: 38238
Don't do std::chrono::seconds(timeToSleep)
. You want something more like:
std::chrono::duration<double>(timeToSleep)
Alternatively, if timeToSleep
is not measured in seconds, you can pass a ratio as a template parameter to duration
. See here (and the examples there) for more information.
Upvotes: 42
Reputation: 1361
Making the answer from @Cornstalks a little more generic, you could define a function like this:
template <typename T>
auto seconds_to_duration(T seconds) {
return std::chrono::duration<T, std::ratio<1>>(seconds);
}
This will convert a seconds value of any primitive type to a chrono duration. Use it like this:
const double timeToSleep = GetTimeToSleep();
std::this_thread_sleep_for(seconds_to_duration(timeToSleep));
Upvotes: 6
Reputation: 454
const unsigned long timeToSleep = static_cast<unsigned long>( GetTimeToSleep() * 1000 );
std::this_thread::sleep_for(std::chrono::milliseconds(timeToSleep));
Upvotes: 4
Reputation: 47854
std::chrono::milliseconds duration(timeToSleep);
std::this_thread::sleep_for( duration );
Upvotes: 0