Given a std::chrono::sys_seconds time
, one might expect to reassign time
from its clock with something like:
time = decltype(time)::clock::now();
However, this would likely fail, because decltype(time)::clock::duration
has nothing to do with decltype(time)
. Instead it is a predefined unit(likely finer than seconds
), so you would have to manually cast it to a coarser unit.
Which means you would need to write something like:
time = std::chrono::time_point_cast<decltype(time)::duration>(decltype(time)::clock::now());
So my question is if there is a shorter syntax to do this?
CodePudding user response:
an obvious solution is just write your own function
template<typename Clock, typename Duration>
void SetNow(std::chrono::time_point<Clock,Duration>& time){
time = std::chrono::time_point_cast<Duration>(Clock::now());
}
// use
void foo(){
auto time = std::chrono::system_clock::now();
SetNow(time);
}
you can also do some fancy overload
struct Now_t{
template<typename Clock,typename Duration>
operator std::chrono::time_point<Clock,Duration>()const{
return std::chrono::time_point_cast<Duration>(Clock::now());
}
consteval Now_t operator()()const{return {};} // enable time = Now();
} Now;
// use
void foo() {
auto time = std::chrono::system_clock::now();
time = Now;
time = Now();
}
CodePudding user response:
If you're in a generic context where you don't know the precise type of time
, then I find it convenient to set up using declarations for clock
and duration
:
template <class TimePoint>
void
assign(TimePoint& time)
{
using clock = typename TimePoint::clock;
using duration = typename TimePoint::duration;
time = std::chrono::floor<duration>(clock::now());
}
I chose floor
as the rounding mode (always down) so that this will have the same behavior prior to the epoch as after. Some clock's current time can be prior to the epoch, such as file_clock
on gcc. But if you prefer truncation towards zero, time_point_cast
will work as well.