问题
The title says it all.
I have to implement a function that receives a std::chrono::system_clock::duration value and that needs to convert it into a timeval sruct so I can pass it to some system function.
回答1:
More general implementation.
template<typename Duration>
void to_timeval(Duration&& d, struct timeval & tv) {
std::chrono::seconds const sec = std::chrono::duration_cast<std::chrono::seconds>(d);
tv.tv_sec = sec.count();
tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(d - sec).count();
}
UPDATE:
Separate methods like to_timeval()
are not too convenient. Where is overloading power? We have just hardcoded type timeval
into name of function to_timeval()
. It's not C++ way. I want to pass struct timeval
into, for example, std::chrono::duration_cast()
and get my chrono
-result and vice versa.
So, we can extend std::chrono::duration_cast
(of course, at your own risk). Enjoy.
namespace std {
namespace chrono {
namespace detail {
template<typename From, typename To>
struct posix_duration_cast;
// chrono -> timeval caster
template<typename Rep, typename Period>
struct posix_duration_cast< std::chrono::duration<Rep, Period>, struct timeval > {
static struct timeval cast(std::chrono::duration<Rep, Period> const& d) {
struct timeval tv;
std::chrono::seconds const sec = std::chrono::duration_cast<std::chrono::seconds>(d);
tv.tv_sec = sec.count();
tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(d - sec).count();
return std::move(tv);
}
};
// timeval -> chrono caster
template<typename Rep, typename Period>
struct posix_duration_cast< struct timeval, std::chrono::duration<Rep, Period> > {
static std::chrono::duration<Rep, Period> cast(struct timeval const & tv) {
return std::chrono::duration_cast< std::chrono::duration<Rep, Period> >(
std::chrono::seconds(tv.tv_sec) + std::chrono::microseconds(tv.tv_usec)
);
}
};
}
// chrono -> timeval
template<typename T, typename Rep, typename Period>
auto duration_cast(std::chrono::duration<Rep, Period> const& d)
-> std::enable_if_t< std::is_same<T, struct timeval>::value, struct timeval >
{
return detail::posix_duration_cast< std::chrono::duration<Rep, Period>, timeval >::cast(d);
}
// timeval -> chrono
template<typename Duration>
Duration duration_cast(struct timeval const& tv) {
return detail::posix_duration_cast< struct timeval, Duration >::cast(tv);
}
} // chrono
} // std
It's just example. As alternative we can implement own duration_cast()
and in some cases forward it into std::chrono::duration_cast()
.
And we remember about struct timespec
.
回答2:
Let d be the input duration value and tv the output timeval structure filled by the convert function. Note: the function sets the timeval to 0 if the duration is negative.
void convert( const std::chrono::system_clock::duration &d, timeval &tv )
{
chrono::microseconds usec = chrono::duration_cast<chrono::microseconds>(d);
if( usec <= chrono::microseconds(0) )
tv.tv_sec = tv.tv_usec = 0;
else
{
tv.tv_sec = usec.count()/1000000;
tv.tv_usec = usec.count()%1000000;
}
}
来源:https://stackoverflow.com/questions/17402657/how-to-convert-stdchronosystem-clockduration-into-struct-timeval