|
Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
|
The 3.x line is a major revision: it requires C++23, renames several core types, and removes a few things. This guide lists every change that affects source code, with the before/after for each. Most everyday code — literals, arithmetic, conversions — is unchanged; the renames are concentrated in the type spellings and the value-extraction call.
| 2.x | 3.x | What to do |
|---|---|---|
| C++14 | C++23 | Compile with -std=c++23 (or /std:c++latest on MSVC). |
| meter_t, second_t, … (singular _t aliases) | meters<double> or meters | Replace meter_t with meters (CTAD) or meters<double>. |
| x() to read the value | x.value(), x.raw(), or x.to<T>() | Replace x() with x.value(). operator() is removed. |
| units::math::sqrt(x) | sqrt(x) (or units::sqrt(x)) | Drop the math::; the functions are found by ADL. |
| units::length::meters | units::meters also works | Optional — the dimension namespaces are now inline. |
| unit_t<...> | unit<...> | The class template was renamed (first argument is now a conversion_factor). |
| base_unit / category | dimension | Renamed throughout. |
| unit (the tag type) | conversion_factor | Renamed. |
| unit_value_t | removed | Use a constexpr quantity value instead. |
| cpow | pow | Renamed. |
The rest of this page expands each of these.
3.x requires C++23. The 2.x line targeted C++14. There is no configuration that makes 3.x build on an older standard; the class-based named types, the concepts, and the constexpr math all depend on it. If you cannot move to C++23, stay on the 2.x series.
In 2.x, the common spelling for a double-backed quantity was the singular alias meter_t. Those aliases are gone. Use the plural class template, with or without an explicit representation:
meters<double> and meters name the same type. See CTAD and ADL.
The biggest source-level change. In 2.x you extracted the underlying value by calling the quantity; operator() no longer exists.
For most units value() and raw() return the same number; they differ for ratio-dimensionless units such as percent (50_pct.value() == 0.5, 50_pct.raw() == 50) — see the FAQ.
The units::math namespace was removed. The unit-aware <cmath> functions now live in units and are found by argument-dependent lookup, so you call them unqualified:
The per-dimension namespaces (units::length, units::mass, …) still exist, but they are inline within units, so the short form works:
The dimension namespace is still useful to disambiguate a unit name shared across dimensions — for example units::mass::pounds versus units::force::pounds.
If your code names the library's internal vocabulary (most application code does not), note:
The compile-time unit_value_t mechanism is gone. Its use case — a value known at compile time — is served directly by a constexpr quantity, since the quantity types are themselves constexpr-friendly:
Literals (5.0_m, 60.0_mi, 1.0_hr), arithmetic and its dimensional results, implicit lossless conversions, std::cout <<, to_string, and the trait-based programming style all work as before. Much 2.x code compiles under 3.x after the _t→plural and () → .value() substitutions plus the C++23 switch.
Beyond the renames, 3.x adds capabilities: readable compiler diagnostics (type safety), std::chrono interop (chrono), a concept vocabulary for your own templates, std::hash and std::numeric_limits support, NaN/infinity handling, optional JSON serialization, and the Visual Studio debugger visualizer. See the changelog.