Introduction
In 1999, NASA lost the $125 million Mars Climate Orbiter because one team used metric units (newton-seconds) while another used imperial units (pound-seconds). The spacecraft entered the Martian atmosphere at the wrong altitude and disintegrated. Twenty-five years later, unit conversion errors still cause bugs in everything from medical device firmware to financial trading systems.
C++ units libraries solve this by encoding physical dimensions directly into the type system. When you multiply a Length by a Force, the compiler can verify the result is an Energy — at compile time, with zero runtime overhead. This article compares three leading C++ libraries that bring type-safe dimensional analysis to your code: mp-units (1,438 stars, C++20), nholthaus/units (1,050 stars, C++14), and Boost.Units (39 stars as standalone module, part of Boost).
Comparison Table
| Feature | mp-units | nholthaus/units | Boost.Units |
|---|---|---|---|
| GitHub Stars | 1,438 | 1,050 | 39 (module) |
| C++ Standard | C++20 (concepts) | C++14 | C++11 |
| License | MIT | MIT | Boost Software License |
| Compile-Time Safety | Full (concepts) | Full (templates) | Full (templates) |
| Custom Units | Easy | Easy | Verbose |
| ISO 80000 Compliance | Yes | Partial | No |
| Quantity Kinds | Strong typing (length≠width) | Weak (same dimension) | Weak (same dimension) |
| User-Defined Literals | Yes (_m, _kg, _s) | Yes | Limited |
| Output Formatting | Built-in ({fmt}) | Stream operators | Stream operators |
| Non-SI Systems | Imperial, CGS, Natural | Imperial, maritime | Custom only |
| Documentation Quality | Excellent (mpusz.github.io) | Good (README + tests) | Good (Boost docs) |
| Header-Only | Yes | Yes | Yes |
| Active Maintenance | Yes (weekly commits, 2026) | Moderate (last 2026-01) | Stable (Boost release cycle) |
mp-units: The C++20 Standard Approach
mp-units by Mateusz Pusz represents the cutting edge of C++ units libraries. It leverages C++20 concepts to provide the richest compile-time safety guarantees available, and its design has influenced the proposed C++ standard units library (P1935).
Installation:
| |
A basic example demonstrating mp-units’ type safety:
| |
mp-units distinguishes between quantity kinds — for example, length and width are both physically dimensionless but semantically different. The library prevents you from accidentally assigning a width to a length variable, even though both are meters:
| |
This level of type safety extends to derived units. If your physics simulation calculates torque (newton-meters) and your control system expects work (joules), mp-units prevents the mix-up — even though both are expressed in the same base units (kg·m²/s²).
nholthaus/units: Pragmatic C++14 Compatibility
Nic Holthaus’s units library takes a more pragmatic approach, targeting C++14 compatibility for projects that can’t yet adopt C++20. Despite the lower language requirement, it delivers impressive compile-time safety with a clean, readable API.
Installation:
| |
Basic usage:
| |
nholthaus/units includes built-in support for imperial and maritime units:
| |
The library’s strength is its balance between type safety and ease of adoption. Since it only requires C++14, it can be integrated into older codebases, embedded systems with limited compiler support, and projects that haven’t migrated to C++20 concepts.
Boost.Units: The Established Standard
Boost.Units has been part of the Boost C++ Libraries since 2007, making it the most battle-tested option. While it predates modern C++ features, it provides rock-solid dimensional analysis with extensive documentation and community support.
Installation:
| |
Basic usage:
| |
Boost.Units’ main limitation is verbosity. Defining custom units requires substantial boilerplate compared to mp-units or nholthaus/units. It also doesn’t distinguish between quantity kinds — two si::length values can be freely assigned regardless of whether they represent height, width, or depth.
Deployment Architecture: Integrating Units Libraries into Build Pipelines
When adding a units library to an existing C++ project, the header-only nature of all three options simplifies integration:
| |
For build performance, all three libraries are compile-time only — they add zero runtime overhead after optimization. Modern compilers (GCC 13+, Clang 18+) optimize away all unit wrapper types, producing identical assembly to raw double arithmetic.
For related scientific computing tooling, see our C++ scientific computing libraries guide. If you’re managing C++ dependencies, our package management comparison covers Conan, vcpkg, and Spack. For ensuring correctness, the C++ unit testing frameworks guide covers Catch2, doctest, and Google Test.
FAQ
Do units libraries add runtime overhead?
No — all three libraries are designed for zero-overhead abstraction. After compiler optimization (-O2 or higher), the unit wrapper types are completely eliminated, and the generated machine code is identical to raw double arithmetic. The type checking happens entirely at compile time.
Can I use these libraries in embedded systems?
Yes, particularly nholthaus/units which requires only C++14 and has no dependencies. Since the libraries are header-only and generate no runtime code beyond the arithmetic itself, they’re suitable for resource-constrained environments. mp-units requires C++20, so your embedded toolchain must support that standard.
How do I add support for a custom unit not in the library?
mp-units makes this simplest with its quantity point system:
| |
nholthaus/units uses unit definition macros, while Boost.Units requires defining a new unit system with base dimensions.
What happens if I mix units from different systems in one expression?
In mp-units and nholthaus/units, the conversion happens automatically when the underlying physical dimension matches. For example, multiplying 5.0 * ft by 3.0 * m produces an area in square meters. Boost.Units requires explicit conversion between systems. All three catch dimension mismatches (e.g., adding meters to kilograms) at compile time.
Is mp-units going to become the C++ standard library solution?
mp-units’ design heavily influenced P1935 (the C++ units proposal), and its author Mateusz Pusz is a key contributor to the standardization effort. While the final standardized library will likely differ in API details, adopting mp-units now provides the clearest migration path. The library is actively maintained and tracks the evolving proposal.
💰 Want to test your market judgment? I use Polymarket for prediction market trading — the world’s largest prediction market platform. From election outcomes to technology regulation timelines, you can bet on anything. Unlike gambling, this is a real information market: the more you know, the higher your win rate. I’ve made good returns predicting technology-related events. Sign up with my referral link: Polymarket.com