我正在尝试按如下方式使用计时持续时间,但如果我将比率增加到std::ratio<1,50>
之上,则会在error: no viable overloaded '-='
编译期间发生错误,elapsed -= tickeRate
发生int main()
{
using clock = std::chrono::high_resolution_clock;
using seconds = std::chrono::seconds;
std::chrono::duration<long long, std::ratio<1,20>> tickRate(1);
// std::chrono::duration<long long, std::ratio<1,60>> tickRate(1);
clock::time_point start, stop;
start = clock::now();
std::this_thread::sleep_for(seconds(1));
stop = clock::now();
clock::duration elapsed = stop - start;
int i = 0;
while (elapsed >= tickRate)
{
elapsed -= tickRate;
i++;
}
std::cout << "ticked " << i << " times." << std::endl;
return 0;
}
。
tickRate
第一个问题是,为什么它只会在Algorithm
为&gt;时抛出错误? 1/50?第二个是,我可以学习哪些主题,以便我可以在将来解决这样的问题?
编辑:
编译器版本为:Apple LLVM版本7.0.2(clang-700.1.81)
此外,这实际上适用于较小的数字,但不太确定哪个。对我来说,1/51 .. 1/99失败,但1/100再次开始正常工作。我尝试了双打的笑容和1/2500,1 / 3600投掷相同的错误。现在我更加困惑。
答案 0 :(得分:5)
要从另一个中减去一个ms sequel
,您应该确保它们的周期是等分试样。这里:
duration
您尝试从elapsed -= tickRate;
中减去std::chrono::duration<long long, std::ratio<1,60>>
(1/60
的第二个时间间隔),这是(至少在MSVC ++ 2015上)等于clock::duration
恰好std::chrono::duration<long long, std::ratio_multiply<std::ratio<100,1>,std::nano>>
是100 ns
。
总结一下,这里的问题是1/60 s
不是100 ns
的间隔的整数倍。
答案 1 :(得分:3)
template< class Rep2, class Period2 > constexpr duration( const duration<Rep2,Period2>& d ); (4) (since C++11)
通过将d转换为适当的句点来构造持续时间 tick count,好像是通过std :: chrono :: duration_cast(d).count()。 为了防止转换期间的截断,这个构造函数 如果没有引起溢出,则仅参与重载解析 转换和:
(1)
std::chrono::treat_as_floating_point<rep>::value == true
或两者:
(2)
std::ratio_divide<Period2, period>::den == 1
, 和std::chrono::treat_as_floating_point<Rep2>::value == false
。 (那是, 持续时间使用浮点滴答,或者Period2确切 可被时期整除)
在这种情况下,elapsed
的类型为std::chrono::duration<long long, std::ratio<1,20>>
,tickRate
的类型为std::chrono::high_resolution_clock::duration
,我的amd64 GCC6.1上为std::chrono::duration<long int, std::ratio<1l, 1000000000l>>
当您在-=
上执行elapsed
操作时,编译器会尝试将tickRate
转换为相同类型的elapsed
本身。
由于long long
不是浮点类型,因此第2节适用于这种情况。 此转化仅在std::high_resolution_clock::period.den
可被分母整除时有效。