# mp-units for C++: Domain-Correct Quantities and Units

> mp-units is a C++20-and-later library for dimensional analysis, unit conversion, and quantity-kind safety based on ISO 80000. It targets physics, engineering, and scientific software where compatible dimensions can conceal incompatible domain meanings.

**mpusz/mp-units** — The Domain-Correct Quantities and Units Library for C++ — full quantity kind safety, ISO 80000 compliant, C++29 standardization candidate.

- Repository: https://github.com/mpusz/mp-units
- Website: https://mpusz.github.io/mp-units/
- Stars: 1,492 · Forks: 131
- Language: C++
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/mpusz-mp-units

## Why mp-units Goes Beyond Dimensional Analysis

mp-units addresses a problem that ordinary numeric types leave open: values can have compatible dimensions while still representing different physical concepts. The README gives frequency versus radioactive activity as an example. Both can be expressed in inverse seconds, but they are not interchangeable in every API. It also distinguishes absorbed dose from dose equivalent, and plane angle from solid angle. These distinctions are represented through compile-time types rather than left to documentation or code review.

The library is based on the International System of Quantities from ISO 80000, exposed through the `isq` namespace. A function can require a specific quantity such as `isq::kinetic_energy[J]`, rather than accepting any value carrying the broad `J` unit. This is useful when a domain has several quantities that share a unit but carry different meaning.

The intended users are C++ developers working with physics, engineering, scientific computing, metrology, and other domain-specific numeric models. The type system also applies outside physics. The README says that developers can define strong types for item counts, financial values, identifiers, or other numeric abstractions that should not be silently mixed.

The project targets Modern C++, beginning with C++20, and is described as a candidate for C++29 standardization through proposal P3045. It is therefore suited to projects that can accept a modern language baseline rather than older compilers or pre-C++20 codebases.

## How mp-units Represents Values and Units

The central mechanism is the `quantity` template. Its type carries a unit and, when needed, an ISQ quantity kind. Arithmetic can therefore be checked while expressions are compiled. Unit expressions are composable, and the library supports systems of quantities and units rather than only a fixed collection of named enumerations.

The following example comes from the README. It demonstrates dimension checking and a domain-specific function signature. The README then rejects a quantity with the right broad unit but the wrong physical kind.

```cpp
#include <mp-units/systems/isq.h>
#include <mp-units/systems/si.h>

using namespace mp_units;
using namespace mp_units::si::unit_symbols;

static_assert(1 * km / (1 * s) == 1000 * m / s);

void calculate_trajectory(quantity<isq::kinetic_energy[J]> e);
```

The README assigns `123 * J` to `quantity<isq::kinetic_energy[J]>` and passes it to `calculate_trajectory`. Passing a `quantity<isq::potential_energy[J]>` is documented as invalid, even though both quantities use `J`. It also rejects assigning `Sv` to a `Gy` quantity, because absorbed dose and dose equivalent have the same dimensional representation but different quantity kinds.

The README describes value-preserving conversions and says dimensional analysis happens at compile time with zero runtime overhead. It also lists scalar, vector, and tensor quantities, affine space support, natural units, and a strong angular system as features. The repository summary does not include benchmark results, so performance should not be inferred from comparative wording in the README.

## Installing mp-units and Starting a First Real Use

The README does not provide a complete installation or package-manager command. It identifies Conan and CMake workflows through repository CI badges and links to the Conan Center package page. The linked documentation and package page are the appropriate sources for a reproducible installation procedure; no unlisted command or compiler flag should be guessed.

A first real use can still be written directly from the README example. Save the example as a C++ source file, include the two system headers, and compile it with a compiler configuration that supports the project's C++20 requirements. The exact compiler flags are not stated in the README.

Define a function that accepts kinetic energy, create a kinetic-energy quantity, and call that function:

```cpp
int main()
{
  quantity<isq::potential_energy[J]> Ep = 42 * J;
  quantity<isq::kinetic_energy[J]> Ek = 123 * J;
  calculate_trajectory(Ek);
}
```

The documented result is successful compilation for the kinetic-energy value. Calling the function with `Ep` instead of `Ek` is invalid because the function requires `isq::kinetic_energy[J]`. The earlier static assertion should also compile, expressing that one kilometre per second equals one thousand metres per second in the library's SI representation.

The repository's `example/` directory contains files such as `hello_units.cpp`, `avg_speed.cpp`, `currency.cpp`, and `si_constants.cpp`. These names show that practical examples are included, but the README does not reproduce their contents or associated build commands.

## Custom Domains, Affine Quantities, and Extension Points

mp-units is not limited to the SI examples in the README. Its framework can extend beyond physics by defining semantically distinct numeric types. This matters where a bare integer or floating-point value has an implicit meaning. A count of items, an identifier, and a monetary amount may all be numerically compatible without being safe to add or compare.

The library also includes affine space strong types called `quantity` and `quantity_point`. That distinction matters where a value is measured relative to a reference point rather than being only an amount or difference. The README names this as a safety feature, but its available text does not include a complete `quantity_point` program. This article therefore does not invent constructors or operations for that type.

Custom dimensions, quantities, and units are described as possible in a single line of code. That is useful for teams that need to map their own terminology into the type system. Customization also transfers design responsibility to the application. A poorly defined custom quantity can be too broad, too narrow, or inconsistent with neighboring types. The library can prevent an accidental conversion only when the domain model itself expresses the distinction correctly.

The README describes the API as macro-free and modules-ready. It also states that the library has no external dependencies and is freestanding-capable. Those characteristics can reduce integration friction, but they do not remove compiler support requirements or the need to model units consistently.

## Limitations and Situations Where mp-units Is the Wrong Tool

The main cost is conceptual and compile-time cost, not a documented runtime dependency. Developers must decide which quantities are distinct, which conversions are valid, and how application APIs should expose them. Once those types enter function signatures, changing them can require work across a codebase. The README emphasizes compile-time analysis and readable errors, but it provides no measurements of compile duration or upgrade effort.

mp-units is the wrong choice when a program only needs simple numeric arithmetic and has no meaningful distinction between compatible quantities. An extensive unit taxonomy can make such code harder to read without preventing a real error. It is also a poor fit for a project that cannot adopt C++20 or later, since the README defines the library as Modern C++ for C++20 and later.

The library does not determine which domain semantics are correct. It can distinguish `isq::potential_energy[J]` from `isq::kinetic_energy[J]` when the application selects those types, but it cannot decide whether a sensor value already represents the correct physical quantity. Custom domains likewise require explicit definitions and naming discipline.

The README does not document a rollback procedure, a compatibility matrix for every compiler, or a complete upgrade policy. Those are documentation boundaries. They are not evidence that the repository lacks related configuration or tests.

## Comparing mp-units with Plain Numeric Types

A realistic alternative is to use primitive numeric types such as `double` or `int` and enforce units through local conventions. This approach has a simpler setup and keeps APIs familiar. Its tradeoff is that unit information is often absent from the type, so passing metres to a function expecting seconds can compile when both are represented by the same primitive type.

Another alternative is a narrow unit wrapper or a domain-specific type library. Such a wrapper may model only a small set of units and domain quantities, which can keep the API smaller. mp-units takes a broader approach through systems of quantities and units, ISQ quantity kinds, affine quantities, scalar, vector, and tensor quantities, natural units, and custom extensions. According to the README, this broader vocabulary is intended to catch errors that dimensional analysis alone cannot detect.

The difference is therefore not simply extra arithmetic support. A plain `double` carries a value without its unit. A quantity type can carry a unit and, for ISQ code, a quantity kind. That additional checking fits scientific and safety-sensitive code, while the extra vocabulary is less attractive for small utilities with simple requirements.

## Maintenance, Licensing, and Upgrade Signals

The repository is not archived. Its last push was on 2026-10-15, which is a recent repository status. Recent releases include `v2.5.0` on 2025-12-24, `v2.4.0` on 2024-11-05, and `v2.3.0` on 2024-09-27. These release entries show versioned releases, but they do not by themselves establish a compatibility policy or a guaranteed upgrade cadence.

The project is licensed under MIT. That identifier is relevant when comparing the library with an organization's open-source policy, but this article does not provide legal advice. Users should review `LICENSE.md` for the exact terms and obligations.

Upgrade cost depends on how widely `quantity`, `isq`, unit symbols, and custom domain types appear in public APIs. Because the library attaches safety information to types crossing function and module boundaries, changing those types can affect callers, serialization code, build configuration, and tests. The repository includes `CHANGELOG.md`, `test/`, `example/`, and CI workflows. Those are concrete places to inspect when evaluating a release, although the README does not summarize their compatibility guarantees.

## Conclusion

Adopt mp-units when accidental mixing of dimensions or domain quantities would create costly scientific or engineering defects, especially if the project already uses C++20 or later. Do not choose it for a small application that needs only plain numeric values and accepts unchecked arithmetic. Verify first that the compiler and build configuration support the required language level, then check that mp-units represents the intended domain distinctions and conversions. The library is a good fit when type-level domain checking is part of the design, but its value still depends on getting that domain model right.

## FAQ

### What is mp-units used for in C++?

mp-units provides compile-time dimensional analysis, unit conversion, and quantity-kind safety for C++20 and later. It can distinguish quantities that share dimensions but represent different concepts, such as kinetic energy and potential energy.

### Does mp-units support custom quantities and units?

Yes. The README says that custom dimensions, quantities, and units can be defined, and it describes strongly typed numerics for domains such as item counts, financial values, and identifiers.

### How do I install mp-units?

The README does not include a complete installation command. It points to the project documentation and identifies Conan and CMake workflows through repository links, so installation details should be taken from those documented sources.

## Sources

- [License: MIT](https://github.com/mpusz/mp-units/blob/master/LICENSE)
- [mpusz/mp-units on GitHub](https://github.com/mpusz/mp-units)
- [Project website](https://mpusz.github.io/mp-units/)
- [README](https://github.com/mpusz/mp-units/blob/master/README.md)
- [Releases](https://github.com/mpusz/mp-units/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mpusz-mp-units
