gpt4 book ai didi

c++ - 如何将 std::chrono::time_point 转换为 long 并返回?

转载 作者:IT老高 更新时间:2023-10-28 13:23:03 30 4
gpt4 key购买 nike

我需要将 std::chrono::time_pointlong 类型(64 位整数)相互转换。我开始使用 std::chrono ...

这是我的代码:

int main ()
{
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();

auto epoch = now.time_since_epoch();
auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
long duration = value.count();


std::chrono::duration<long> dur(duration);

std::chrono::time_point<std::chrono::system_clock> dt(dur);

if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}

此代码编译,但未显示成功。

为什么最后的dtnow不同?

该代码缺少什么?

最佳答案

std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();

这是auto的好地方:

auto now = std::chrono::system_clock::now();

由于您希望以 毫秒 精度进行流量,因此最好继续并在 time_point 中进行转换:

auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);

now_ms 是一个 time_point,基于 system_clock,但精度为 milliseconds 而不是任何精度你的 system_clock 有。

auto epoch = now_ms.time_since_epoch();

epoch 现在具有类型 std::chrono::milliseconds。下一条语句本质上变成了无操作(只是复制而不进行转换):

auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);

这里:

long duration = value.count();

在您和我的代码中,duration 保存自 system_clock 的纪元以来的 毫秒 数。

这个:

std::chrono::duration<long> dur(duration);

创建一个用 long 表示的 duration,精度为 seconds。这有效地 reinterpret_castvalue 中保存的 milliseconds 转换为 seconds。这是一个逻辑错误。正确的代码如下所示:

std::chrono::milliseconds dur(duration);

这一行:

std::chrono::time_point<std::chrono::system_clock> dt(dur);

基于 system_clock 创建一个 time_point,能够将精度保持在 system_clock 的 native 精度(通常小于毫秒) )。但是,运行时值将正确反射(reflect)整数毫秒数(假设我更正了 dur 的类型)。

即使进行了更正,该测试也会(几乎总是)失败:

if (dt != now)

因为 dt 拥有整数个 milliseconds,而 now 拥有比 millisecond 更精细的整数个刻度code>(例如 microsecondsnanoseconds)。因此,只有在 system_clock::now() 返回整数 milliseconds 的极少数情况下,测试才会通过。

但你可以:

if (dt != now_ms)

现在您将可靠地获得预期结果。

把它们放在一起:

int main ()
{
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);

auto value = now_ms.time_since_epoch();
long duration = value.count();

std::chrono::milliseconds dur(duration);

std::chrono::time_point<std::chrono::system_clock> dt(dur);

if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}

我个人觉得所有 std::chrono 过于冗长,所以我将其编码为:

int main ()
{
using namespace std::chrono;
auto now = system_clock::now();
auto now_ms = time_point_cast<milliseconds>(now);

auto value = now_ms.time_since_epoch();
long duration = value.count();

milliseconds dur(duration);

time_point<system_clock> dt(dur);

if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}

哪个会可靠输出:

Success.

最后,我建议消除临时变量,以将 time_point 和整数类型之间的代码转换减少到最低限度。这些转换是危险的,因此您编写的操作裸整数类型的代码越少越好:

int main ()
{
using namespace std::chrono;
// Get current time with precision of milliseconds
auto now = time_point_cast<milliseconds>(system_clock::now());
// sys_milliseconds is type time_point<system_clock, milliseconds>
using sys_milliseconds = decltype(now);
// Convert time_point to signed integral type
auto integral_duration = now.time_since_epoch().count();
// Convert signed integral type to time_point
sys_milliseconds dt{milliseconds{integral_duration}};
// test
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}

上面的主要危险是在返回 time_point 的路上将 integral_duration 解释为 milliseconds。减轻这种风险的一种可能方法是编写:

    sys_milliseconds dt{sys_milliseconds::duration{integral_duration}};

这将风险降低到只需确保您在退出时使用 sys_milliseconds 并在返回途中的两个地方使用。

还有一个例子:假设您要转换为表示 system_clock 支持的任何持续时间的积分(微秒,10th 微秒或纳秒)。然后您不必担心如上所述指定毫秒。代码简化为:

int main ()
{
using namespace std::chrono;
// Get current time with native precision
auto now = system_clock::now();
// Convert time_point to signed integral type
auto integral_duration = now.time_since_epoch().count();
// Convert signed integral type to time_point
system_clock::time_point dt{system_clock::duration{integral_duration}};
// test
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}

这是可行的,但是如果您在一个平台上运行一半的转换(从积分转换),而在另一个平台上运行另一半转换(从积分转换),您将面临 system_clock::duration 的风险两次转换会有不同的精度。

关于c++ - 如何将 std::chrono::time_point 转换为 long 并返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31255486/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com