我需要将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;
}
此代码编译,但未显示成功。
为什么dt
最后与now
不同?
该代码缺少什么?
答案 0 :(得分:114)
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
这是auto
的好地方:
auto now = std::chrono::system_clock::now();
由于您希望以millisecond
精度进行流量,因此最好继续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
保留自milliseconds
时代以来system_clock
的数量。
此:
std::chrono::duration<long> dur(duration);
创建以duration
表示的long
,精度为seconds
。这有效reinterpret_cast
milliseconds
value
到seconds
。这是一个逻辑错误。正确的代码如下:
std::chrono::milliseconds dur(duration);
这一行:
std::chrono::time_point<std::chrono::system_clock> dt(dur);
基于time_point
创建system_clock
,能够保持system_clock
本机精度(通常小于毫秒)的精度。但是,运行时值将正确反映保持的整数毫秒数(假设我对dur
的类型进行了更正)。
即使进行了更正,这项测试也会(几乎总是)失败但是:
if (dt != now)
由于dt
包含整数milliseconds
,但now
包含的整数个刻度比millisecond
更精细(例如microseconds
或{{ 1}})。因此,只有在nanoseconds
返回整数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;
}
的路上将integral_duration
解释为milliseconds
。减轻这种风险的一种可能方法是写:
time_point
这样可以降低风险,只需确保在出路时使用 sys_milliseconds dt{sys_milliseconds::duration{integral_duration}};
,并在返回途中的两个地方使用。{/ p>
还有一个例子:让我们说你要转换成一个积分来表示任何持续时间sys_milliseconds
支持(微秒,10 th of microseconds或nanoseconds)。那么你不必担心如上所述指定毫秒。代码简化为:
system_clock
这是有效的,但是如果你在另一个平台上运行一半转换(转换为积分)而另一半转平(从积分转换为积分),则会冒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;
}
具有不同精度的风险两次转换。
答案 1 :(得分:1)
我还要注意,有两种方法可以获得时间点的ms数。我不确定哪一个更好,我已经对它们进行了基准测试,它们都具有相同的性能,所以我想这是一个偏好问题。也许霍华德可能会说:
auto now = system_clock::now();
//Cast the time point to ms, then get its duration, then get the duration's count.
auto ms = time_point_cast<milliseconds>(now).time_since_epoch().count();
//Get the time point's duration, then cast to ms, then get its count.
auto ms = duration_cast<milliseconds>(tpBid.time_since_epoch()).count();
第一个在我的脑海中从左到右读得更清楚。
答案 2 :(得分:0)
time_point
objects仅支持与其他time_point
或duration
个对象进行算术运算。
您需要将long
转换为指定单位的duration
,然后您的代码才能正常运行。
答案 3 :(得分:0)
单行:
long value_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now()).time_since_epoch()).count();