nholthaus / units

a compile-time, header-only, dimensional analysis and unit conversion library built on c++14 with no dependencies.
http://nholthaus.github.io/units/
MIT License
934 stars 134 forks source link

Added std::common_type<T, T> specialization to ensure the return type… #314

Open Guillaume227 opened 1 year ago

Guillaume227 commented 1 year ago

Added std::common_type<T, T> specialization to ensure the return type off arithmetic operators matches the input type when the two inputs have the same type. That fixes ternary operator use cases. See #313

JohelEGP commented 1 year ago

Returning the same type as the template parameters would regress returning the GCD of the conversion factors, like https://en.cppreference.com/w/cpp/chrono/duration/common_type.

For example, let D be std::duration<int, std::ratio<2, 2>>. std::common_type_t<D, D> should be std::duration<int> (with period std::ratio<1>), not D.

Guillaume227 commented 1 year ago

Ok thanks for raising this subtlety, which is not covered by the current test suite. I am going to need to think about how to factor that in. For reference, here is the error I am trying to fix when using the ternary operator: auto deg = true ? degrees<double>(1) : degrees<double>(2) - degrees<double>(90);

/home/ggiraud/mcaura/units/unitTests/main.cpp:657:25: error: operands to ‘?:’ have different types 
‘units::angle::degrees<double>’ {aka ‘units::unit<units::angle::degrees_, double, units::linear_scale>’} and 
‘std::common_type_t<units::unit<units::angle::degrees_, double, units::linear_scale>, units::unit<units::angle::degrees_, double, 
units::linear_scale> >’ {aka ‘units::unit<units::conversion_factor<std::ratio<1, 180>, 
units::dimension_t<units::dim<units::dimension::angle_tag, std::ratio<1, 1> > >, std::ratio<1>, std::ratio<0> >, double, 
units::linear_scale>’}