|
Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
|
Common questions, and the reasoning behind the answers. For a hands-on start see getting started; for the full API on a page see the cheat sheet.
Because 1_m and 2_m are meters<int>, and integer division truncates — exactly as 1 / 2 is 0 for plain int. The representation follows the literal: 5_m is meters<int>, 5.0_m is meters<double>. Write the decimal point (1.0_m / 2.0_m == 0.5) or name a floating-point type when you want fractional results. See CTAD and ADL.
For ordinary units they return the same number. They differ for ratio-dimensionless units such as percent: .raw() returns the stored value (the point count) while .value() returns the normalized fraction.
Use .value() when you want the quantity's value in its own units (the usual case), and .raw() when you specifically want the stored number. Both are distinct from .to<T>(), which casts to a chosen representation. operator() — the 2.x accessor — no longer exists; see the migration guide.
Because a bare number has no dimension, and letting it silently become a length (or a length silently become a number) is exactly the class of bug the library exists to prevent. Construct explicitly (meters d(5.0)), or extract explicitly (d.value()), at the boundary with non-units code. The one exception is a dimensionless quantity, which does convert to and from arithmetic types implicitly — because it genuinely has no dimension.
Implicit conversions are allowed only when they are lossless. Converting feet to meters into an int-backed quantity would truncate, so it does not happen implicitly:
When you intend a narrowing conversion, ask for it explicitly with .to<T>() or unit_cast<T>(). Both apply a static_cast to the target type, so .to<int>() truncates toward zero (e.g. 2.7 -> 2, -2.7 -> -2); if you need rounding, round the value yourself first (see the rounding note in unit conversions). See type safety and unit conversions.
Yes — time quantities convert implicitly to and from std::chrono::duration in both directions, and the two mix in a single expression via std::common_type. See chrono interop.
Caveat: conversion happens at assignment and argument boundaries, not inside a raw mixed expression. 1.5_min + std::chrono::seconds{30} does not compile; assign the chrono value to a units quantity first (or vice versa), then combine.
Define UNIT_LIB_DEFAULT_TYPE before including the library (for example to float on an embedded target). See configuration.
Define UNIT_LIB_DISABLE_IOSTREAM (or set the UNITS_DISABLE_IOSTREAM CMake option). Arithmetic, conversions, and name()/abbreviation() still work; only the stream/string rendering is removed. See disabling iostream.
Some platform headers define macros that clash with the SI abbreviations. #undef the offending macro before including units. The known ones: #undef pascal on Windows, and several single-letter #undefs (_U, _L, …) on some ARM toolchains. The Tesla literal is spelled _Te rather than _T for this reason (_T is a hardcoded Windows macro). See literals.
The unit-aware math functions are found by ADL, which considers them alongside anything else in scope. If a call is genuinely ambiguous, qualify it: units::hypot(a, b). Note also that signbit is provided as std::signbit (to win overload resolution against <cmath>), so call it qualified; isnan/isinf/isfinite are in units and work unqualified.
No. Conversions are compile-time ratio arithmetic, a conversion between equivalent representations emits no code, and a quantity is a trivially-copyable value the size of its underlying type. See efficiency.
C++23, on GCC 13+, Clang 19+, or MSVC 2022. The 2.x series is the option for older toolchains. See migrating from 2.x.
Quantities are trivially-copyable value types with no shared state, so passing them by value across threads is safe (the usual rules apply to a shared mutable object, as for any value). The library's errors are compile-time; the operations do not throw.
One line with UNIT_ADD inside namespace units. See defining new units.
Reference the project by name and repository, nholthaus/units (https://github.com/nholthaus/units), with the version tag you used.