On Jul 6, 2016, at 10:45 AM,
ssha...@gmail.com wrote:
>
> The integral chrono duration types (the defaults) only define arithmetic operators for integral literals. They do not provide such operators for floating point literals.
>
> This can lead to very unintuitive behavior if one attempts to multiply by a floating point. Consider the following sample program:
>
> #include <chrono>
> #include <iostream>
>
> int main(int, char**)
> {
> using namespace std::chrono;
> milliseconds base(60 * 1000);
> milliseconds derived = base;
> derived *= 0.8;
>
> std::cout << "Base: " << base.count()
> << ", derived: " << derived.count()
> << std::endl;
> }
>
> This prints 'Base: 60000, Derived: 0', which I doubt is what anybody who writes this code intends.
On the plus side, my complier outputs the following warning by default (not using -Wall):
test.cpp:10:16: warning: implicit conversion from 'double' to 'rep' (aka 'long long') changes value from 0.8 to 0 [-Wliteral-conversion]
derived *= 0.8;
~~ ^~~
1 warning generated.
Gcc does not warn by default, but will if you use -Wfloat-conversion.
I don’t see any warnings at all from VS.
>
> Is there anything that can be done to help people avoid this trap? My first two thoughts were:
> - Declare the non-member floating point overloads as deleted to prevent the implicit conversion to int
> - Just add the floating point overloads
I would not be adverse to restricting these operators using treat_as_floating_point. Though I would want the proposer to actually implement and test such a suggestion first. The rationale to using the trait is so that we correctly handle emulated arithmetic reps (e.g. safe<int>, safe<double>).
Here is how I would recommend fixing the client code:
#include <chrono>
#include <iostream>
int
main()
{
using namespace std::chrono_literals;
using milliseconds = std::chrono::duration<double, std::milli>;
milliseconds base = 1min;
milliseconds derived = base;
derived *= 0.8;
std::cout << "Base: " << base.count()
<< ", derived: " << derived.count()
<< std::endl;
}
Howard