Zam*_*son 14 c++ serialization persistence c++11 c++-chrono
持久化std :: chrono time_point实例然后将它们读回另一个相同类型的实例的正确方法是什么?
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
time_point_t tp = std::chrono::high_resolution_clock::now();
serializer.write(tp);
.
.
.
time_point_t another_tp;
serializer.read(another_tp);
Run Code Online (Sandbox Code Playgroud)
对write/read的调用,假设time_point_t类型的实例可以某种方式转换为字节表示,然后可以将其写入磁盘或套接字等或从磁盘或套接字读取.
Alf建议的可能解决方案如下:
std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();
//Generate POD to write to disk
unsigned long long ns0 = t0.time_since_epoch().count();
//Read POD from disk and attempt to instantiate time_point
std::chrono::high_resolution_clock::duration d(ns0)
std::chrono::high_resolution_clock::time_point t1(d);
unsigned long long ns1 = t1.time_since_epoch().count();
if ((t0 != t1) || (ns0 != ns1))
{
std::cout << "Error time points don't match!\n";
}
Run Code Online (Sandbox Code Playgroud)
注意:上面的代码有一个错误,因为最终实例化的时间点与原始时间点不匹配.
在旧样式time_t的情况下,人们通常只是根据其sizeof将整个实体写入磁盘,然后以相同的方式读取它 - 简而言之,新的std :: chrono类型的等价物是什么?
How*_*ant 18
从磁盘或套接字读取意味着您可能正在读取未执行写入的应用程序实例.在这种情况下,单独序列化持续时间是不够的.
A time_point是duration自未指定时期以来的一段时间.这个时代可能是任何事物.在我的计算机上,std::chrono::high_resolution_clock每当计算机启动时,时代就会出现.即此时钟报告自引导以来的纳秒数.
如果一个应用程序写入time_since_epoch().count(),计算机将重新启动,然后另一个(甚至相同的)应用程序将其读回,读入值没有任何意义,除非您碰巧知道该数量靴子之间的时间.
为了可靠地序列化,time_point必须安排作者和读者就某个时代达成一致,然后确保time_point书面和阅读是关于那个时代的.例如,可以安排使用POSIX时代:1970年的新世界.
事实证明,std::chrono::system_clock我所知道的每一个实现都使用Unix时间,这是从1970年新年开始测量的近似UTC.然而,我知道没有共同的时代std::chrono::high_resolution_clock.
只有当你能够以某种方式确保读者和作者时钟在一个共同的时代上达成一致时,你才能将time_point序列化为持续时间.
该time_point构造需要duration,你可以得到一个duration从成员time_since_epoch.因此,问题减少了序列化一个duration值.并且duration有一个带有许多刻度的构造函数,以及一个count产生刻度数的成员函数.
所有这些只是通过std::chrono::time_point谷歌搜索和查看cppreference文档谷歌让我上了.
阅读文档通常是个好主意.
附录:一个例子.
#include <chrono>
#include <iostream>
#include <typeinfo>
using namespace std;
auto main() -> int
{
using Clock = chrono::high_resolution_clock;
using Time_point = Clock::time_point;
using Duration = Clock::duration;
Time_point const t0 = Clock::now();
//Generate POD to write to disk
Duration::rep const ns0 = t0.time_since_epoch().count();
//Read POD from disk and attempt to instantiate time_point
Duration const d(ns0);
Time_point const t1(d);
cout << "Basic number type is " << typeid( ns0 ).name() << "." << endl;
if( t0 != t1 )
{
cout << "Error time points don't match!" << endl;
}
else
{
cout << "Reconstituted time is OK." << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
使用Visual C++ 12.0报告的基本类型是__int64,即long long在Windows中使用g ++ 4.8.2时,报告的类型是x,这可能意味着相同.
对于两个编译器,重构时间与原始时间相同.
附录:正如Dina在评论中指出的那样,从C++ 14开始,C++标准没有指定时代,因此为了使这个工作跨越机器或使用不同的时钟,有必要添加额外的步骤来规范化时代.序列化数据,例如最自然地为Posix时间,即自1970年1月1日星期四00:00:00协调世界时(UTC)以来的时间.
| 归档时间: |
|
| 查看次数: |
3963 次 |
| 最近记录: |