I am trying to use chrono durations as follows but if I increase the ratio to be anything above std::ratio<1,50>
it throws an error during compilation that error: no viable overloaded '-='
for when elapsed -= tickeRate
occurs.
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;
}
The first question is, why does it only throw the error when tickRate
is > 1/50? The second is, what topic can I study so that I can reason through problems like this in the future?
Edit:
Compiler version is: Apple LLVM version 7.0.2 (clang-700.1.81)
Additionally this actually works with smaller numbers but not quite sure which. For me, 1/51 .. 1/99 fail, but 1/100 starts working fine again. I tried doubles for grins and 1/2500, 1/3600 throw the same error. Now I'm even more confused.
template< class Rep2, class Period2 > constexpr duration( const duration<Rep2,Period2>& d ); (4) (since C++11)
Constructs a duration by converting d to an appropriate period and tick count, as if by std::chrono::duration_cast(d).count(). In order to prevent truncation during conversion, this constructor only participates in overload resolution if no overflow is induced by conversion and:
(1)
std::chrono::treat_as_floating_point<rep>::value == true
or both:
(2)
std::ratio_divide<Period2, period>::den == 1
, andstd::chrono::treat_as_floating_point<Rep2>::value == false
. (that is, either the duration uses floating-point ticks, or Period2 is exactly divisible by period)
In this case, the type of elapsed
is std::chrono::duration<long long, std::ratio<1,20>>
, while that of tickRate
is std::chrono::high_resolution_clock::duration
, which is std::chrono::duration<long int, std::ratio<1l, 1000000000l>>
on my amd64 GCC6.1.
When you perform a -=
operation on elapsed
, the compiler will try to convert tickRate
to the same type of elapsed
itself.
Since long long
is not an floating point type, clause 2 will be suitable for this case. This conversion is only valid when std::high_resolution_clock::period.den
is divisible by your denominator.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments