Division is similar to multiplication, but instead of adding
exponents, we must subtract them. Rather than writing out a near
duplicate of plus_f, we can use the following trick to make
minus_f much simpler:

Here minus_f::apply uses inheritance to expose the nested
type of its base class, mpl::minus, so we don't have to
write:

typedef typename ...::type type

We don't have to write
typename here (in fact, it would be illegal), because the
compiler knows that dependent names in apply's initializer
list must be base classes. [2] This powerful
simplification is known as metafunction forwarding; we'll apply
it often as the book goes on. [3]

Users of EDG-based compilers should consult the book's Appendix C
for a caveat about metafunction forwarding. You can tell whether
you have an EDG compiler by checking the preprocessor symbol
__EDG_VERSION__, which is defined by all EDG-based compilers.

Syntactic tricks notwithstanding, writing trivial classes to wrap
existing metafunctions is going to get boring pretty quickly. Even
though the definition of minus_f was far less verbose than that
of plus_f, it's still an awful lot to type. Fortunately, MPL gives
us a much simpler way to pass metafunctions around. Instead of
building a whole metafunction class, we can invoke transform
this way:

typename mpl::transform<D1,D2, mpl::minus<_1,_2> >::type

Those funny looking arguments (_1 and _2) are known as
placeholders, and they signify that when the transform's
BinaryOperation is invoked, its first and second arguments will
be passed on to minus in the positions indicated by _1 and
_2, respectively. The whole type mpl::minus<_1,_2> is
known as a placeholder expression.

Note

MPL's placeholders are in the mpl::placeholders
namespace and defined in boost/mpl/placeholders.hpp. In
this book we will usually assume that you have written:

If we got everything right, rounding_error should be very close
to zero. These are boring calculations, but they're just the sort
of thing that could ruin a whole program (or worse) if you got them
wrong. If we had written a/f instead of f/a, there would have
been a compilation error, preventing a mistake from propagating
throughout our program.