
The problem with these non-standard units is that they don't really form a well-defined unit system. ... We have, however, supplied a number of examples of how to roll your own unit system... )
I agree with Zach and also want to be able to define units without having to "roll my own unit system".
There is no way to avoid having some tag class to differentiate units having the same dimensional signature - it's just impossible to do it and preserve the ability to do zero-runtime overhead calculations. You don't have to define a system, but every unit needs to have a unique dimensional signature and a tag. Consider definition of the unit for gallon : struct imperial : public ordinal<1000> { }; typedef unit<volume_type,imperial> imperial_gallon; struct us : public ordinal<1001> { }; typedef unit<volume_type,us> us_gallon; The ordinal is necessary to be able to sort dimension lists and can't be gotten around because there's no way to have the compiler generate a unique enumerated sequence of values. It's hard to get much more concise than this... You can then define conversions between the two : /// convert imperial gallons to us gallons template<class Y> class conversion_helper< quantity<unit<volume_type,imperial>,Y>, quantity<unit<volume_type,us>,Y> > { public: typedef quantity<unit<volume_type,imperial>,Y> from_quantity_type; typedef quantity<unit<volume_type,us>,Y> to_quantity_type; static to_quantity_type convert(const from_quantity_type& source) { const typename from_quantity_type::value_type& in (source.value()); return to_quantity_type::from_value(in.value() *1.2009499255); } }; /// convert us gallons to imperial gallons template<class Y> class conversion_helper< quantity<unit<volume_type,us>,Y>, quantity<unit<volume_type,imperial>,Y> > { public: typedef quantity<unit<volume_type,us>,Y> from_quantity_type; typedef quantity<unit<volume_type,imperial>,Y> to_quantity_type; static to_quantity_type convert(const from_quantity_type& source) { const typename from_quantity_type::value_type& in (source.value()); return to_quantity_type::from_value(in.value()/ 1.2009499255); } }; That's all you need to do to define your own units. If you want them to be implicitly convertible, then you need to also define that : template<> struct is_implicitly_convertible<unit<volume_type,imperial>, unit<volume_type,us> > : public mpl_::true_ { }; template<> struct is_implicitly_convertible<unit<volume_type,us>, unit<volume_type,imperial> > : public mpl_::true_ { }; Matthias