Because Boost.Units includes plane and solid angle units in the SI system,
torque and energy are, in fact, distinguishable (see torque).
In addition, energy is a true scalar
quantity, while torque, despite having the same units as energy if plane
angle is not included, is in fact a pseudovector.
Thus, a value type representing pseudovectors and encapsulating their algebra
could also be implemented.

There are, however, a few SI units that are dimensionally indistinguishable
within the SI system. These include the becquerel,
which has units identical to frequency (Hz), and the sievert,
which is degenerate with the gray.
In cases such as this, the proper way to treat this difference is to recognize
that expanding the set of base dimensions can provide disambiguation. For
example, adding a base dimension for radioactive decays would allow the becquerel
to be written as decays/second, differentiating it from the signature of
hertz, which is simply 1/second.

What should this print? If only heterogeneous systems are available it would
print 3.14159+ rad Why? Well, asin
would return a quantity<dimensionless>
effectively losing the information that degrees are being used. In order
to propogate this extra information we need homogeneous systems.

This only breaks generic code--which ought to break anyway. The only literal
value that ought to be converted to a quantity by generic code is zero, which
should be handled by the default constructor. In addition, consider the search
and replace problem allowing this poses:

quantity<si::length>q(1.0);

Here, the intent is clear - we want a length of one in the SI system, which
is one meter. However, imagine some well-intentioned coder attempting to
reuse this code, but to have it perform the calculations in the CGS unit
system instead. After searching for si:: and replacing it with cgs:: , we have:

quantity<cgs::length>q(1.0);

Unfortunately, the meaning of this statement has suddenly changed from one
meter to one centimeter. In contrast, as implemented, we begin with:

quantity<si::length>q(1.0*si::meter);

and, after search and replace:

quantity<cgs::length>q(1.0*cgs::meter);

which gives us an error. Even if the code has a @using namespace boost::units::si;
declaration, the latter is still safe, with:

usingnamespaceboost::units::si;quantity<length>q(1.0*meter);

going to

usingnamespaceboost::units::cgs;quantity<length>q(1.0*meter);

The latter will involve an explicit conversion from meters to centimeters,
but the value remains correct.