...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Front Page / Tutorial: Metafunctions and Higher-Order Metaprogramming / Dimensional Analysis |
The first rule of doing physical calculations on paper is that the numbers being manipulated don't stand alone: most quantities have attached dimensions, to be ignored at our peril. As computations become more complex, keeping track of dimensions is what keeps us from inadvertently assigning a mass to what should be a length or adding acceleration to velocity — it establishes a type system for numbers.
Manual checking of types is tedious, and as a result, it's also error-prone. When human beings become bored, their attention wanders and they tend to make mistakes. Doesn't type checking seem like the sort of job a computer might be good at, though? If we could establish a framework of C++ types for dimensions and quantities, we might be able to catch errors in formulae before they cause serious problems in the real world.
Preventing quantities with different dimensions from interoperating isn't hard; we could simply represent dimensions as classes that only work with dimensions of the same type. What makes this problem interesting is that different dimensions can be combined, via multiplication or division, to produce arbitrarily complex new dimensions. For example, take Newton's law, which relates force to mass and acceleration:
F = ma
Since mass and acceleration have different dimensions, the dimensions of force must somehow capture their combination. In fact, the dimensions of acceleration are already just such a composite, a change in velocity over time:
dv/dt
Since velocity is just change in distance (l) over time (t), the fundamental dimensions of acceleration are:
(l/t)/t = l/t2
And indeed, acceleration is commonly measured in "meters per second squared." It follows that the dimensions of force must be:
ml/t2
and force is commonly measured in kg(m/s2), or "kilogram-meters per second squared." When multiplying quantities of mass and acceleration, we multiply their dimensions as well and carry the result along, which helps us to ensure that the result is meaningful. The formal name for this bookkeeping is dimensional analysis, and our next task will be to implement its rules in the C++ type system. John Barton and Lee Nackman were the first to show how to do this in their seminal book, Scientific and Engineering C++ [BN94]. We will recast their approach here in metaprogramming terms.
[BN94] | John J. Barton and Lee R. Nackman. Scientific and Engineering C++: an Introduction with Advanced Techniques and Examples. Reading, MA: Addison Wesley. ISBN 0-201-53393-6. 1994. |