|
Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
|
From #include to your first quantities. This assumes a C++23 compiler and that you have the headers available (see integration or just put include/ on your include path).
Include the umbrella header for everything, or a single dimension header for a lighter build, and bring in the literal operators:
units::literals must be brought in with a using directive to write literals such as 5.0_m. The main units namespace holds the quantity types and the unit-aware math functions.
There are four equivalent ways to create a quantity. Pick whichever reads best in context:
meters on its own is a complete type — the compiler deduces meters<double> from the argument. This is CTAD; you can also spell it explicitly as meters<double> (or meters<float>, meters<int>) whenever you want a specific representation.
Note — the decimal point selects int vs double. 5.0_m is meters<double>; 5_m is meters<int>. Integer-backed quantities do integer arithmetic (1_m / 2_m == 0), so write the decimal point when you want fractional results. This is the same rule the language applies to 1 / 2 == 0.
Assigning between compatible units converts implicitly, as long as the conversion is lossless:
A conversion that would lose information (for example into an integer representation) is a compile error, not a silent truncation — see type safety. Conversions are computed at compile time and cost nothing at run time; see efficiency.
Operators return the correct dimension for the result. Name the result type and the compiler verifies your dimensional analysis:
If you get the dimension wrong — meters area = 15.0_m * 5.0_m; — it does not compile, and the message names the type you actually produced (square_meters<double>). Using auto accepts whatever the expression yields:
Caveat — auto turns off the check. With an explicit result type, the compiler verifies the dimensional analysis. With auto, you are asserting that whatever the expression produces is what you intended. Prefer an explicit type where a dimensional mistake would be costly; reach for auto when the result type is genuinely intermediate or verbose.
The unit-aware <cmath> functions are found by ADL — call them unqualified, with no units:: prefix:
pow<N> and sqrt track the dimension (square root of an area is a length); trigonometric functions require an angle. The full set is in math functions.
When you must hand a value to an API that does not speak units, extract it explicitly:
There is no implicit conversion from a dimensioned quantity to double (that would defeat the type safety); a dimensionless quantity is the exception and converts implicitly. operator() — the 2.x way to extract a value — no longer exists; use .value(), .raw(), or .to<T>().