forked from mpusz/mp-units
feat: quantities can now be multiplied and divided by units
This commit is contained in:
@@ -16,10 +16,9 @@ static_assert(1 * h == 3600 * s);
|
||||
static_assert(1 * km + 1 * m == 1001 * m);
|
||||
|
||||
// derived quantities
|
||||
inline constexpr auto kmph = km / h;
|
||||
static_assert(1 * km / (1 * s) == 1000 * (m / s));
|
||||
static_assert(2 * kmph * (2 * h) == 4 * km);
|
||||
static_assert(2 * km / (2 * kmph) == 1 * h);
|
||||
static_assert(1 * km / (1 * s) == 1000 * m / s);
|
||||
static_assert(2 * km / h * (2 * h) == 4 * km);
|
||||
static_assert(2 * km / (2 * km / h) == 1 * h);
|
||||
|
||||
static_assert(2 * m * (3 * m) == 6 * m2);
|
||||
|
||||
@@ -59,7 +58,7 @@ int main()
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
using namespace mp_units::international::unit_symbols;
|
||||
|
||||
constexpr quantity v1 = 110 * (km / h);
|
||||
constexpr quantity v1 = 110 * km / h;
|
||||
constexpr quantity v2 = 70 * mph;
|
||||
constexpr quantity v3 = avg_speed(220. * isq::distance[km], 2 * h);
|
||||
constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * h);
|
||||
|
||||
@@ -92,47 +92,6 @@ In the **mp-units** library, both a number and a unit have to always be explicit
|
||||
form a quantity.
|
||||
|
||||
|
||||
## Why `60 * km / h` does not compile?
|
||||
|
||||
The library design does not allow multiplying or dividing a quantity (the result of `60 * km`)
|
||||
by another unit. This significantly limits the number of possible errors and surprises in the
|
||||
quantity equations.
|
||||
|
||||
Consider the following expression:
|
||||
|
||||
```cpp
|
||||
auto q = 60 * km / 2 * h;
|
||||
```
|
||||
|
||||
Looks like `30 km/h`, right? But it is not. If the above code was allowed, it would result
|
||||
in `30 km⋅h`. In case you want to divide `60 * km` by `2 * h` a parenthesis is needed:
|
||||
|
||||
```cpp
|
||||
auto q = 60 * km / (2 * h);
|
||||
```
|
||||
|
||||
Another surprising issue could result from the following code:
|
||||
|
||||
```cpp
|
||||
template<typename T>
|
||||
auto make_length(T v) { return v * si::metre; }
|
||||
|
||||
auto v = 42;
|
||||
auto q = make_length(v);
|
||||
```
|
||||
|
||||
The above might look like a good idea, but consider what would happen in the user provided
|
||||
an already existing quantity:
|
||||
|
||||
```cpp
|
||||
auto v = 42 * m;
|
||||
auto q = make_length(v);
|
||||
```
|
||||
|
||||
Fortunately, with the current design, such issues are detected at compile-time as
|
||||
multiplying or dividing a quantity by a unit is not be supported.
|
||||
|
||||
|
||||
## Why a dimensionless quantity is not just a fundamental arithmetic type?
|
||||
|
||||
In the initial design of this library, the resulting type of division of two quantities was their
|
||||
|
||||
@@ -67,14 +67,9 @@ quantity q = make_quantity<si::metre>(42);
|
||||
Sometimes it might be awkward to type some derived units:
|
||||
|
||||
```cpp
|
||||
quantity speed = 60 * (km / h);
|
||||
quantity speed = 60 * km / h;
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
Please note that `60 * km / h` will not compile. To read more about the rationale for such
|
||||
a design please check our [FAQ](faq.md#why-dont-we-use-udls-to-create-a-quantity).
|
||||
|
||||
In case such a unit is used a lot in the project, a user can easily provide a nicely named
|
||||
wrapper for it with:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user