微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 C++11 中处理毫秒的正确方法是什么

如何解决在 C++11 中处理毫秒的正确方法是什么

我正在尝试将项目的基本开发库从 C++98 更新到 C++11。

在dev库中,有很多关于时间的函数,比如

uint64_t getCurrentMSTime()
{
    struct timeval stv;
    gettimeofday(&stv,NULL);
    uint64_t ms = stv.tv_sec ;
    ms = ms * 1000 + stv.tv_usec / 1000;
    return ms;
}

我正在尝试使用 C++11 的 std::chrono 更改它。

目前看来我有两个选择,一个是返回time_point,另一个是立即返回std::chrono::milliseconds::rep

std::chrono::time_point<std::chrono::system_clock> getCurrentTime1() {
    return std::chrono::system_clock::Now();
}

std::chrono::milliseconds::rep getCurrentTime2() {
    return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::Now().time_since_epoch()).count();
}

嗯,我知道第一个更灵活,因为它返回一个 time_point,这意味着我们可以将其转换为毫秒、纳秒、秒等,而第二个仅返回毫秒。

>

但假设开发人员仅使用毫秒,因此我们可以忽略灵活问题。

在这种情况下,哪个更好?

顺便说一句,开发人员会做这样的事情:std::map<std::string,???> mp;。所以我的代码将决定 ??? 部分。

std::map<std::string,std::chrono::time_point<std::chrono::system_clock>> mp{std::string("abc"),getCurrentTime1()};
对比
std::map<std::string,std::milliseconds::rep> mp{std::string("abc"),getCurrentTime2()};

哪个更好?或者它们几乎相同?

解决方法

我同意当前接受的答案,即您应该重视类型安全,而不是返回整数类型。但是我不同意返回 milliseconds 是最好的。

类型安全也适用于时间点和持续时间之间的差异。例如,添加两个持续时间是非常有意义的。但是添加两个时间点是无意义的,尽管您可以将它们相减以产生持续时间。

由于getCurrentTime()的意思是返回当前时间点,所以应该返回一个std::chrono::time_point。可以轻松选择基于 time_pointsystem_clock 精度返回 milliseconds

std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>
getCurrentTime()
{
    return std::chrono::time_point_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now());
}

在 C++20 中,这种类型有一个方便的类型别名,使其更容易拼写。如果您想先行一步,可以为自己创建这样的类型别名:

std::chrono::sys_time<std::chrono::milliseconds>
getCurrentTime()
{
    return std::chrono::time_point_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now());
}

或者您可以创建一个更短的名称以在您的应用程序中使用,也许:

using MSTime = std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>;
...
MSTime
getCurrentMSTime()
{
    return std::chrono::time_point_cast<MSTime::duration>(
        std::chrono::system_clock::now());
}
,

您当然不想丢弃 <chrono> 提供的类型信息。如果您立即将从系统时钟获得的 time_point 转换为整数值,您同样可以很好地保持旧函数的原样。

相反,请预先决定是否要处理与时代相关的时间点。旧函数暗示你想要这个,所以你的函数应该是这样的;

std::chrono::milliseconds getDurationSinceEpoch()
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch());
}

但假设开发人员仅使用毫秒,因此我们可以忽略灵活问题

不要。你在这里得到的是免费的。每当此要求发生变化,并且某些开发人员以任何分辨率将 getDurationSinceEpoch() 返回值与持续时间混合在一起时,它就会变得非常脆弱。通过将正确的单元烘焙到您的函数中,您可以防止将来出现错误。

最后,您希望您的地图具有此签名:

std::map<std::string,std::chrono::milliseconds>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。