无法在 std::chrono::time_point 之间转换
Cannot convert between std::chrono::time_point s
为什么以下函数无法编译,并出现错误
cannot convert from 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<double,std::nano>>' to 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::steady_clock::duration>'
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const TimePoint CorrectedEpoch = TimePoint() - EquivalentJulianYearInDays + LeapSecondCorrection;
return CorrectedEpoch + days;
}
注意:TimePoint()
被 return 函数 TimePoint
替代,但 return 值不/不应该相关。
修改它以使用整数持续时间允许它编译,但我丢失了小数天部分,这是不希望的。
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<int, std::ratio<86400>> Days;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
using std::chrono::duration_cast;
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const TimePoint CorrectedEpoch = TimePoint() - duration_cast<Days>(EquivalentJulianYearInDays) + duration_cast<Days>(LeapSecondCorrection);
return CorrectedEpoch + duration_cast<Days>(days);
}
<chrono>
库的设计使得截断错误不会隐式发生。这是因为截断错误很容易发生,并且经常导致信息的意外丢失。
错误信息:
cannot convert from time_point<steady_clock, duration<double,std::nano>>
to time_point<steady_clock, steady_clock::duration>
表示已尝试从小数纳秒(基于双精度)到整纳秒(基于整数)的隐式转换,但不允许。事实证明,每个 steady_clock::duration
恰好是纳秒,尽管没有指定。
如果截断是您想要的(如本例),可以使用 duration_cast
或 time_point_cast
截断为零。在 C++17 中,添加了 floor
、ceil
和 round
截断模式。
这是执行库拒绝隐式执行的截断转换的最直接方法:
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const TimePoint CorrectedEpoch =
std::chrono::time_point_cast<TimePoint::duration>(
TimePoint() - EquivalentJulianYearInDays + LeapSecondCorrection);
return std::chrono::time_point_cast<TimePoint::duration>(CorrectedEpoch + days);
}
第一次转换是必要的,因为表达式 TimePoint() - EquivalentJulianYearInDays + LeapSecondCorrection
的类型为 time_point<high_resolution_clock, duration<double, nano>>
(浮点纳秒 time_point),目标类型是基于整数的纳秒 time_point.第二次转换同上。
auto
可用于稍微清理此代码,并避免以下转换之一:
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const auto CorrectedEpoch = TimePoint() -
EquivalentJulianYearInDays + LeapSecondCorrection;
return std::chrono::time_point_cast<TimePoint::duration>(CorrectedEpoch + days);
}
现在 CorrectedEpoch
是基于双精度的纳秒 time_point,但该细节对您的算法并不重要。
此外,尼可波拉斯关于 high_resolution_clock
的可疑使用的评论是有根据的。如果您从不将 TimePoint
与来自 high_resolution_clock::now()
的 high_resolution_clock::time_point
混合使用,您的代码可能会起作用。但是,使用已记录的 2000-01-01 12:00:00 UTC 纪元创建自己的自定义时钟会更安全。然后任何意外的混合都会在编译时被捕获。
为什么以下函数无法编译,并出现错误
cannot convert from 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<double,std::nano>>' to 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::steady_clock::duration>'
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const TimePoint CorrectedEpoch = TimePoint() - EquivalentJulianYearInDays + LeapSecondCorrection;
return CorrectedEpoch + days;
}
注意:TimePoint()
被 return 函数 TimePoint
替代,但 return 值不/不应该相关。
修改它以使用整数持续时间允许它编译,但我丢失了小数天部分,这是不希望的。
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<int, std::ratio<86400>> Days;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
using std::chrono::duration_cast;
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const TimePoint CorrectedEpoch = TimePoint() - duration_cast<Days>(EquivalentJulianYearInDays) + duration_cast<Days>(LeapSecondCorrection);
return CorrectedEpoch + duration_cast<Days>(days);
}
<chrono>
库的设计使得截断错误不会隐式发生。这是因为截断错误很容易发生,并且经常导致信息的意外丢失。
错误信息:
cannot convert from
time_point<steady_clock, duration<double,std::nano>>
totime_point<steady_clock, steady_clock::duration>
表示已尝试从小数纳秒(基于双精度)到整纳秒(基于整数)的隐式转换,但不允许。事实证明,每个 steady_clock::duration
恰好是纳秒,尽管没有指定。
如果截断是您想要的(如本例),可以使用 duration_cast
或 time_point_cast
截断为零。在 C++17 中,添加了 floor
、ceil
和 round
截断模式。
这是执行库拒绝隐式执行的截断转换的最直接方法:
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const TimePoint CorrectedEpoch =
std::chrono::time_point_cast<TimePoint::duration>(
TimePoint() - EquivalentJulianYearInDays + LeapSecondCorrection);
return std::chrono::time_point_cast<TimePoint::duration>(CorrectedEpoch + days);
}
第一次转换是必要的,因为表达式 TimePoint() - EquivalentJulianYearInDays + LeapSecondCorrection
的类型为 time_point<high_resolution_clock, duration<double, nano>>
(浮点纳秒 time_point),目标类型是基于整数的纳秒 time_point.第二次转换同上。
auto
可用于稍微清理此代码,并避免以下转换之一:
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimePoint;
typedef std::chrono::duration<double, std::ratio<86400>> JulianDays;
TimePoint JulianDaysToUTC(const JulianDays& days)
{
static const JulianDays EquivalentJulianYearInDays(2451545.0);
static const JulianDays LeapSecondCorrection(0.0008);
static const auto CorrectedEpoch = TimePoint() -
EquivalentJulianYearInDays + LeapSecondCorrection;
return std::chrono::time_point_cast<TimePoint::duration>(CorrectedEpoch + days);
}
现在 CorrectedEpoch
是基于双精度的纳秒 time_point,但该细节对您的算法并不重要。
此外,尼可波拉斯关于 high_resolution_clock
的可疑使用的评论是有根据的。如果您从不将 TimePoint
与来自 high_resolution_clock::now()
的 high_resolution_clock::time_point
混合使用,您的代码可能会起作用。但是,使用已记录的 2000-01-01 12:00:00 UTC 纪元创建自己的自定义时钟会更安全。然后任何意外的混合都会在编译时被捕获。