mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-30 18:37:15 +02:00
docs: "Why derived units order is not preserved from the multiplication?" chapter added to FAQ
This commit is contained in:
@ -139,6 +139,71 @@ all the properties of scaled units and is consistent with the rest of the librar
|
|||||||
[the Dimensionless Quantities chapter](../users_guide/framework_basics/dimensionless_quantities.md).
|
[the Dimensionless Quantities chapter](../users_guide/framework_basics/dimensionless_quantities.md).
|
||||||
|
|
||||||
|
|
||||||
|
## Why derived units order is not preserved from the multiplication?
|
||||||
|
|
||||||
|
It might be surprising, but the quantities and units multiplication order does not impact the order
|
||||||
|
of components in the derived unit. Let's try the following example:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::println("{}", 42 * kW * h);
|
||||||
|
constexpr auto kWh = kW * h;
|
||||||
|
std::println("{}", 42 * kWh);
|
||||||
|
```
|
||||||
|
|
||||||
|
The above prints:
|
||||||
|
|
||||||
|
```text
|
||||||
|
42 h kW
|
||||||
|
42 h kW
|
||||||
|
```
|
||||||
|
|
||||||
|
Some users could expect to see `42 kWh` or `42 kW h` in the output. It is not the case and for
|
||||||
|
a very good reason. As stated in
|
||||||
|
[Simplifying the resulting expression templates](../users_guide/framework_basics/interface_introduction.md#simplifying-the-resulting-expression-templates),
|
||||||
|
to be able to reason about and simplify units, the library needs to order them in an appropriate
|
||||||
|
order.
|
||||||
|
|
||||||
|
Maybe this default order could be improved a bit, but according to international standards,
|
||||||
|
there is no generic ordering rule. Various quantities use different, often domain-specific,
|
||||||
|
ordering of derived unit components.
|
||||||
|
|
||||||
|
Let's see what [SI](../appendix/references.md#SIBrochure) says here:
|
||||||
|
|
||||||
|
| Derived quantity | Symbol | Derived unit expressed in terms of base units |
|
||||||
|
|----------------------------|:------:|:---------------------------------------------:|
|
||||||
|
| _electric field strength_ | V m⁻¹ | kg m s⁻³ A⁻¹ |
|
||||||
|
| _electric charge density_ | C m⁻³ | A s m⁻³ |
|
||||||
|
| _exposure (x- and γ-rays)_ | C kg⁻¹ | A s kg⁻¹ |
|
||||||
|
|
||||||
|
However, there is a workaround. A user can define its own named unit for a derived unit and provide
|
||||||
|
the custom symbol text that suits the project's requirements. For example, the above case could be
|
||||||
|
addressed with:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct kilowatt_hour final : named_unit<"kWh", kW * h> {} kilowatt_hour;
|
||||||
|
inline constexpr auto kWh = kilowatt_hour;
|
||||||
|
```
|
||||||
|
|
||||||
|
With the above, we can refactor the above code to:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::println("{}", 42 * kWh);
|
||||||
|
std::println("{}", (42 * kW * h).in(kWh));
|
||||||
|
```
|
||||||
|
|
||||||
|
Both lines will produce an expected "42 kWh" unit in the output.
|
||||||
|
|
||||||
|
!!! important
|
||||||
|
|
||||||
|
Please note that this makes the entire "kWh" a single, indivisible entity that is not subject
|
||||||
|
to simplification rules. This means that `42 * kWh / (2 * h)` will result with `21 kWh/h`
|
||||||
|
rather than `21 kW`. To get the latter, the user needs to explicitly provide a new derived unit:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::println("{}", (42 * kWh / (2 * h)).in(kW));
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Why do the identifiers for concepts in the library use `CamelCase`?
|
## Why do the identifiers for concepts in the library use `CamelCase`?
|
||||||
|
|
||||||
Initially, C++20 was meant to use `CamelCase` for all the concept identifiers. All the concepts
|
Initially, C++20 was meant to use `CamelCase` for all the concept identifiers. All the concepts
|
||||||
|
Reference in New Issue
Block a user