为什么小的chrono :: durations不会减去?

时间:2016-08-05 14:33:19

标签: c++ c++11

我正在尝试按如下方式使用计时持续时间,但如果我将比率增加到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投掷相同的错误。现在我更加困惑。

2 个答案:

答案 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可被分母整除时有效。