我需要将 std::chrono::time_point
转换为 long
类型(整数 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;
}
此代码编译,但未显示成功。
为什么最后 --- 与 now
dt
不同?
该代码缺少什么?
原文由 Mendes 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是
auto
的好地方:由于您想以
millisecond
精度进行流量,因此最好继续并在time_point
中进行转换:now_ms
is atime_point
, based onsystem_clock
, but with the precision ofmilliseconds
instead of whatever precision yoursystem_clock
有。epoch
现在有类型std::chrono::milliseconds
。下一条语句本质上变成了无操作(仅进行复制而不进行转换):这里:
在您和我的代码中,
duration
拥有自milliseconds
的时代以来的system_clock
的数量。这个:
创建一个
duration
用long
表示,精度为seconds
。这实际上是reinterpret_cast
smilliseconds
保存在value
到seconds
。这是一个逻辑错误。正确的代码如下所示:这一行:
创建一个
time_point
基于system_clock
,能够保持system_clock
的本机精度(通常比毫秒)。但是,运行时值将正确反映整数毫秒数(假设我更正了dur
的类型)。即使进行了更正,此测试也会(几乎总是)失败:
因为
dt
拥有整数个milliseconds
,但是now
拥有比 amillisecond
更精细的整数个刻度microseconds
67eebeeabd0351a---
或nanoseconds
)。因此,只有在system_clock::now()
返回整数milliseconds
的极少数情况下,测试才会通过。但您可以改为:
现在,您将可靠地获得预期的结果。
把它们放在一起:
就我个人而言,我发现所有
std::chrono
过于冗长,所以我将其编码为:这将可靠地输出:
最后,我建议消除临时变量以将
time_point
和整数类型之间的代码转换减少到最低限度。这些转换是危险的,因此您编写的操作裸整数类型的代码越少越好:上面的主要危险 不是 在返回
milliseconds
的路上将integral_duration
解释为time_point
。减轻这种风险的一种可能方法是编写:这将风险降低到只需确保您在退出时使用
sys_milliseconds
并在返回途中的两个地方使用。再举一个例子:假设您要转换为表示任何持续时间 ---
system_clock
支持(微秒、10 微秒或纳秒)的积分。然后您不必担心如上所述指定毫秒。代码简化为:这行得通,但是如果您在一个平台上运行一半转换(从积分转换为整数),而在另一个平台上运行另一半转换(从积分转换),您将面临
system_clock::duration
两者的精度不同的风险转换。