持久化std :: chrono time_point实例 [英] Persisting std::chrono time_point instances
问题描述
保存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);
调用write / read,假设类型为time_point_t的实例可以以某种方式转换为
Alf建议的可能解决方案如下:
std :: chrono :: high_resolution_clock :: time_point t0 = std :: chrono :: high_resolution_clock :: now
//生成POD以写入磁盘
unsigned long long ns0 = t0.time_since_epoch()。count();
//从磁盘读取POD并尝试实例化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< 错误时间点不匹配!\\\
;
}
上面的代码有一个错误,因为最终的实例化时间点与原始的时间点不匹配。
在旧式的time_t的情况下,
time_point
构造函数需要一个 duration
,你可以得到 duration
来自成员 time_since_epoch
。因此问题减少为序列化 duration
值。和 duration
有一个构造函数,它接受多个ticks,并且一个成员函数 count
产生tick的数量。
所有这些只需通过googling std :: chrono :: time_point
,并查看cppreference文档google登陆我
这通常是一个好主意,请阅读 文档 。
:一个例子。 #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();
//生成POD以写入磁盘
Duration :: rep const ns0 = t0.time_since_epoch()。count();
//从磁盘读取POD并尝试实例化time_point
持续时间const d(ns0);
Time_point const t1(d);
cout<< 基本号码类型是< typeid(ns0).name()<< 。 << endl
if(t0!= t1)
{
cout< 错误时间点不匹配! << endl
}
else
{
cout< 重组时间OK。 << endl
}
}
使用Visual C ++ 12.0,报告的基本类型是 __ int64
,即 long long
,而使用g ++ 4.8.2在Windows中报告的类型是 x
,这可能意味着相同。
对于两个编译器,重构时间与原始时间相同。
附录:由于 Dina在注释中注释,在C ++ 14中,C ++标准没有指定时期,所以为了使它跨机器或不同的时钟工作,需要添加额外的步骤来标准化时期对于序列化数据,最自然的是 Posix时间,即自00:00:00以来的时间世界协调时间(UTC) ),1970年1月1日,星期四。
What is the correct way to persist std::chrono time_point instances and then read them back into another instance of the same type?
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);
The calls to write/read, assume that the instance of type time_point_t, can be somehow converted to a byte representation, which can then be written to or read from a disk or a socket etc.
A possible solution suggested by Alf is as follows:
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";
}
Note: The above code has a bug as the final instantiated time point does not match the original.
In the case of of the old style time_t, one typically just writes the entire entity to disk based on its sizeof and then reads it back the same way - In short what would be the equivalent for the new std::chrono types?
the time_point
constructor takes a duration
, and you can get a duration
from member time_since_epoch
. thus the question reduces to serialize a duration
value. and duration
has a constructor that takes a number of ticks, and a member function count
that produces the number of ticks.
all this just by googling std::chrono::time_point
and looking at the cppreference documentation google landed me on.
it's often a good idea to read the documentation.
Addendum: an example.
#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;
}
}
With Visual C++ 12.0 the reported basic type is __int64
, i.e. long long
, while with g++ 4.8.2 in Windows the reported type is x
, which presumably means the same.
With both compilers the reconstituted time is identical to the original.
Addendum: As noted by Dina in the comments, as of C++14 the C++ standard doesn't specify the epoch, and so to make this work across machines or with different clocks it's necessary to add additional steps that normalize the epoch for the serialized data, e.g. and most naturally to Posix time, i.e. time since since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970.
这篇关于持久化std :: chrono time_point实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!