Skip to content

Commit

Permalink
Restrict implicit dimensionless ctor to unscaled values
Browse files Browse the repository at this point in the history
Implicit conversions to/from built-in types appear to be a potential
source of confusion for dimensionless units with a scaling factor (e.g.,
percent<>) [0]. Disallowing implicit conversions in those cases might be
a not-terrible way to eliminate this potential for confusion without
decreasing usability.

The idea for limiting the implicit conversion to unscaled values was
adapted from mpusz/units [1]. I'm not entirely confident this
implementation is the best approach, but it's at least not obviously
broken.

[0]: nholthaus#301

[1]: mpusz/mp-units#412 (comment)
  • Loading branch information
Alex Wang committed Mar 27, 2023
1 parent 90efb12 commit cc56630
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 4 deletions.
6 changes: 4 additions & 2 deletions include/units/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2277,11 +2277,13 @@ namespace units

/**
* @brief constructor
* @details enable implicit conversions from T types ONLY for linear dimensionless units
* @details enable implicit conversions from T types ONLY for unscaled linear dimensionless units
* @param[in] value value of the unit
*/
template<concepts::losslessly_convertible<T> Ty, concepts::dimensionless Cf = ConversionFactor>
inline constexpr unit(const Ty value) noexcept : linearized_value(NumericalScale::linearize(static_cast<T>(value)))
inline explicit(!std::ratio_equal_v<typename traits::conversion_factor_traits<Cf>::conversion_ratio, std::ratio<1>>) constexpr unit(
const Ty value) noexcept
: linearized_value(NumericalScale::linearize(static_cast<T>(value)))
{
}

Expand Down
4 changes: 2 additions & 2 deletions unitTests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3055,10 +3055,10 @@ TEST(Consistency, recovers_input_values)
TEST(Consistency, percent)
{
percent<double> a(50);
percent<double> b = 50;
// percent<double> b = 50;

EXPECT_DOUBLE_EQ(a, 50_pct);
EXPECT_DOUBLE_EQ(b, 50_pct);
// EXPECT_DOUBLE_EQ(b, 50_pct);
}

TEST_F(UnitType, identity)
Expand Down

0 comments on commit cc56630

Please sign in to comment.