|
Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
|
When you multiply or divide quantities you get a new kind: meters / seconds is a velocity, mass * acceleration is a force. The friendly name for that result — meters_per_second, newtons — lives in the result's dimension header (<units/velocity.h>, <units/force.h>). Two small habits keep computed results naming and dispatching the same way throughout a program.
If a translation unit names or prints a computed result, include that result's dimension header, not just the headers of the operands. Dividing meters by seconds yields a velocity, so a file that prints or names that result reads best with <units/velocity.h> in scope:
This is a best practice, not a requirement — the value and the dimension are always correct either way. With the header, the result carries its friendly name (5 mps) and diagnostics read meters_per_second; without it, the same value prints in dimension form (5 m s^-1) and diagnostics spell out the underlying type.
Because a result's friendly name comes from its dimension header, whether a computed value matches an overload or specialization written for the concrete named type (meters_per_second) depends on whether that header was in scope. A function keyed on the concrete type can match the same computed value in one file and miss it in another that included a different set of headers.
Constrain on the dimension concept instead — units::Velocity, units::Force, units::Length, and one for every dimension. A concept classifies by dimension, so it matches a result the same way everywhere, independent of the header set:
The concept is the robust choice for any function, trait, or overload that dispatches on a computed quantity. Every dimension has one, generated alongside its traits::is_<dimension>_unit trait — see the concepts reference.