c++ 如何从clock::now()中重新分配一个time_point?

z2acfund  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(130)

给定一个std::chrono::sys_seconds time,我们可能期望用如下的语句从它的时钟中重新分配time

time = decltype(time)::clock::now();

但是,这很可能会失败,因为decltype(time)::clock::durationdecltype(time)没有任何关系,而是一个预定义的单位(可能比seconds更细),因此您必须手动将其转换为一个更粗的单位。
这意味着您需要编写如下内容:

time = std::chrono::time_point_cast<decltype(time)::duration>(decltype(time)::clock::now());

所以我的问题是,是否有更短的语法来实现这一点?

bxjv4tth

bxjv4tth1#

一个明显解决方案是编写您自己的函数

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);
}

您还可以进行一些花哨重载

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();
}
i1icjdpr

i1icjdpr2#

如果您在泛型上下文中不知道time的精确类型,那么我发现为clockduration设置using声明很方便:

template <class TimePoint>
void
assign(TimePoint& time)
{
    using clock = typename TimePoint::clock;
    using duration = typename TimePoint::duration;
    time = std::chrono::floor<duration>(clock::now());
}

我选择floor作为舍入模式(总是向下),这样在历元之前和之后的行为是一样的。一些时钟的当前时间可以在历元之前,比如gcc上的file_clock。但是如果你喜欢向零截断,time_point_cast也可以。

相关问题