错误:请求从 std::chrono::time_point 浮点数转换为非标量类型长整型
error: conversion from std::chrono::time_point float to non-scalar type long int requested
我有这段代码,它试图通过添加持续时间来创建新time_point:
// now
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
// duration
std::chrono::duration<float> duration(1.0f / 60.0f); // float in seconds
// now + duration
std::chrono::system_clock::time_point futureTime = now + duration;
但它给了我这个错误
error: conversion from 'std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<float, std::ratio<1, 1000000000> > >' to non-scalar type 'std::chrono::_V2::system_clock::time_point {aka std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >}' requested
# it's over there in the distance --->
# ... again, with some manual formatting:
error:
conversion from
'std::chrono::time_point<std::chrono::_V2::system_clock,
std::chrono::duration<float,
std::ratio<1, 1000000000> > >'
to non-scalar type
'std::chrono::_V2::system_clock::time_point
{aka
std::chrono::time_point<std::chrono::_V2::system_clock,
std::chrono::duration<long int,
std::ratio<1, 1000000000> > >}'
requested
经过一番重度眯眼后,第一个有一个float
,第二个有一个long int
。因此,now (long int) + duration (float)
给出了一个具有一些内部浮点持续时间的time_point,我大概要求将其填充回默认的long int
表示中。
我想最终将这个时间点传递给std::condition_variable::wait_until
.如何强制转换为std::chrono::system_clock::time_point
?
如果我这样做,我会失去什么样的精度(即它是否存储毫秒,在这种情况下我会丢失一些 1/60)?
如果我不转换它,那么编写now + duration
返回的类型有什么很好的简短方法(是的,我可以使用 auto,但为了说将其传递给函数)?
你在问题中所做的分析基本上是正确的。 有几个好方法可以做到这一点。1,2
使用auto
// now
system_clock::time_point now = system_clock::now();
// duration
duration<float> duration(1.0f / 60.0f); // float in seconds
// now + duration
auto futureTime = now + duration;
futureTime
的类型是time_point<system_clock, duration<float, nano>>
。 也就是说,它是一个基于system_clock
的time_point
,存储由float
表示的nanoseconds
。
此类型可以与std::condition_variable::wait_until
一起使用。
将now + duration
放回system_clock::time_point
:
// now
system_clock::time_point now = system_clock::now();
// duration
duration<float> duration(1.0f / 60.0f); // float in seconds
// now + duration
system_clock::time_point futureTime =
time_point_cast<system_clock::duration>(now + duration);
time_point_cast<duration>
这就是你投time_point
的方式。 您必须明确指定希望生成的time_point
具有的持续时间类型。 生成的time_point
将继续基于相同的时钟。 结果将被截断(四舍五入为零)到下一个整数system_clock::duration
(在此平台上nanoseconds
)。
此类型可以与std::condition_variable::wait_until
一起使用。
回合now + duration
回到system_clock::time_point
:
system_clock::time_point futureTime = round<system_clock::duration>(now + duration);
这就像前面的解一样,只不过这个四舍五入到最接近的积分nanoseconds
,以及平局上的偶数nanoseconds
。std::chrono::round
在 C++17 及更高版本中可用。 这将给出最多1ns
与time_point_cast
不同的结果。
如果您没有 C++17 但仍想使用round
,请随意使用这个。
此类型可以与std::condition_variable::wait_until
一起使用。
用积分算术精确表示 1/60
// now
system_clock::time_point now = system_clock::now();
// duration
duration<int, std::ratio<1, 60>> duration{1}; // 1/60 of a second
// now + duration
auto futureTime = now + duration;
人们常说:
不可能精确地表示1/60秒。
但是你可以用<chrono>
:-)duration<int, std::ratio<1, 60>>
以1/60秒为单位计数,使用int
表示形式。duration{1}
是1/60秒。duration{2}
是2/60秒。 等。
auto
在这里真的派上用场了。futureTime
的类型是:time_point<system_clock, duration<system_clock::rep, ratio<1, 3'000'000'000>>>
。 或英语:基于system_clock
的time_point
,使用持续时间,表示类型为system_clock::time_point
使用的任何内容(通常为long long
),周期为1/3nanoseconds
。
事实证明,1/3nanoseconds
是最粗的精度,可以准确地表示system_clock::period
(nanoseconds
在这个平台上)和1/60秒。
<chrono>
会自动为您解决所有这些问题。 要利用它,您所要做的就是使用auto
.
此类型可以与std::condition_variable::wait_until
一起使用。
如果您想回到基于纳秒的system_clock::time_point
,还可以将duration<int, std::ratio<1, 60>>
与time_point_cast
或round
结合使用,如前所述。
总结
哪个最好? 您必须根据应用程序中的其他因素来决定。 通常,最好的是使其余代码更具可读性。
但是你有选择,它们都是不错的选择。 他们都将与std::condition_variable::wait_until
一起工作.
当你探索你的选项时,如果它没有编译,那是因为<chrono>
在编译时捕获你的错误(就像第一个一样)。 如果它可以编译(并且如果您没有使用.count()
或.time_since_epoch()
转义类型系统),那么它就可以工作了。
1本问题的答案假定system_clock::duration
与问题中报告nanoseconds
。 这仅适用于gcc,在Windows和macOS上有所不同。
2为了不迷失在冗长中,我写我的答案好像有一个:
using namespace std::chrono;
在玩。 它使事情更具可读性。
std::condition_variable::wait_until
看起来像这样:(cpp首选项)
template< class Clock, class Duration >
std::cv_status
wait_until( std::unique_lock<std::mutex>& lock,
const std::chrono::time_point<Clock, Duration>& timeout_time );
template< class Clock, class Duration, class Pred >
bool wait_until( std::unique_lock<std::mutex>& lock,
const std::chrono::time_point<Clock, Duration>& timeout_time,
Pred pred );
您可以将任何time_point<C, D>
传递给它。它不必是system_clock::time_point
.system_clock::time_point
只是time_point<system_clock>
.
时钟的确切表示形式是实现定义的,但它必须是整数类型。不可能用整数作为数字和秒作为单位精确地表示(1/60)s
。
now + duration
,其中now
是time_point<C, D1>
型,duration
是duration<R2, P2>
型,是time_point<C, std::common_type_t<duration<R1, P1>, D2>>
型。
- 无法转换类型 C++
- 包含可变参数包的第一个可转换类型的别名的结构
- 将 std::conditional 与不可转换类型(原始与指针)一起使用
- 链接方法时出现转换类型错误
- 如何避免隐式转换类型
- 在多重继承场景中动态强制转换类型
- 编译器不支持的转换类型
- 错误调用功能无法转换类型
- 我想看到一个在整个后缀表达式的上下文中查找转换类型 id 的示例
- 对于动态类型为强制转换类型的对象,dynamic_cast失败
- 无法在初始化中转换类型
- 如何让"auto"转换类型
- 如何通过强制转换类型指针将字符数组转换为uint16_t
- 如何从新运算符+(Template类)返回具有转换类型的对象
- 带有模板的基于枚举的工厂无法转换类型
- 使用SWIG类型映射通过字符串转换类型
- 对于可转换类型,设计比循环依赖项更好
- SWIG不能正确转换类型定义
- 将类型转换扩展到可转换类型的对/元组
- 想要将字符数组的部分转换/类型转换为值