
Just to be concrete, I've reworked your code a bit to eliminate extraneous complexity : #include <iostream> #include <boost/units/base_dimension.hpp> #include <boost/units/base_unit.hpp> #include <boost/units/io.hpp> #include <boost/units/scale.hpp> #include <boost/units/scaled_base_unit.hpp> #include <boost/units/make_system.hpp> #include <boost/units/static_constant.hpp> #include <boost/units/quantity.hpp> #define DECLARE_BASE_UNIT_INFO(base_unit_, name_, symbol_) \ template<> struct base_unit_info<base_unit_> { \ static const char* name() { return name_; } \ static const char* symbol() { return symbol_; } \ }; namespace boost { namespace units { struct data_capacity_base_dimension : base_dimension<data_capacity_base_dimension, 73254> {}; typedef data_capacity_base_dimension::dimension_type data_capacity_dimension; struct bit_base_unit : base_unit<bit_base_unit,data_capacity_dimension, 76389> {}; typedef scaled_base_unit<bit_base_unit, scale<2, static_rational<3> >
byte_base_unit;
typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<10>
kilobyte_base_unit; typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<20> megabyte_base_unit; typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<30> gigabyte_base_unit; typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<40> terabyte_base_unit; typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<50> petabyte_base_unit;
DECLARE_BASE_UNIT_INFO(bit_base_unit, "bit", "b") DECLARE_BASE_UNIT_INFO(byte_base_unit, "byte", "B") DECLARE_BASE_UNIT_INFO(kilobyte_base_unit, "kilobyte", "KB") DECLARE_BASE_UNIT_INFO(megabyte_base_unit, "megabyte", "MB") DECLARE_BASE_UNIT_INFO(gigabyte_base_unit, "gigabyte", "GB") DECLARE_BASE_UNIT_INFO(terabyte_base_unit, "terabyte", "TB") DECLARE_BASE_UNIT_INFO(petabyte_base_unit, "petabyte", "PB") BOOST_UNITS_STATIC_CONSTANT(bit, bit_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(bits, bit_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(byte, byte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(bytes, byte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(kilobyte, kilobyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(kilobytes, kilobyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(megabyte, megabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(megabytes, megabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(gigabyte, gigabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(gigabytes, gigabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(terabyte, terabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(terabytes, terabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(petabyte, petabyte_base_unit::unit_type); BOOST_UNITS_STATIC_CONSTANT(petabytes, petabyte_base_unit::unit_type); } } using namespace boost::units; template<class U,class Y> void outputDataCapacity(const quantity<U,Y>& q) { static const Y bits_per_byte = 8, bits_per_kilobyte = 8*1024, bits_per_megabyte = 8*1024*1024, bits_per_gigabyte = 8*1024*1024*1024; const quantity<bit_base_unit::unit_type,Y> qb(q); const Y qv(qb.value()); if (qb.value() <= bits_per_byte) std::cout << qb << std::endl; else if (qb.value() <= bits_per_kilobyte) std::cout << quantity<byte_base_unit::unit_type,Y>(q) << std::endl; else if (qb.value() <= bits_per_megabyte) std::cout << quantity<kilobyte_base_unit::unit_type,Y>(q) << std::endl; else if (qb.value() <= bits_per_gigabyte) std::cout << quantity<megabyte_base_unit::unit_type,Y>(q) << std::endl; else std::cout << "error..." << std::endl; return; } int main() { quantity<bit_base_unit::unit_type, int> c1(1000 * bits); quantity<byte_base_unit::unit_type, int> c2(1000 * bytes); quantity<kilobyte_base_unit::unit_type, int> c3(1000 * kilobytes); quantity<megabyte_base_unit::unit_type, int> c4(1000 * megabytes); quantity<bit_base_unit::unit_type, int> d1(1 * gigabyte); quantity<byte_base_unit::unit_type, int> d2(1 * gigabyte); quantity<kilobyte_base_unit::unit_type, int> d3(1 * gigabyte); quantity<megabyte_base_unit::unit_type, int> d4(1 * gigabyte); std::cout << c1 << std::endl; std::cout << c2 << std::endl; std::cout << c3 << std::endl; std::cout << c4 << std::endl; std::cout << std::endl; std::cout << d1 << std::endl; std::cout << d2 << std::endl; std::cout << d3 << std::endl; std::cout << d4 << std::endl; std::cout << std::endl; for (double v=1.0;v<=std::pow(2.0,24);v*=2.0) { outputDataCapacity(v*bits); } return 0; } This code compiles and runs correctly and does what you would expect, outputting : 1000 b 1000 B 1000 KB 1000 MB 2147483647 b 1073741824 B 1048576 KB 1024 MB 1 b 2 b 4 b 8 b 2 B 4 B 8 B 16 B 32 B 64 B 128 B 256 B 512 B 1024 B 2 KB 4 KB 8 KB 16 KB 32 KB 64 KB 128 KB 256 KB 512 KB 1024 KB error... The conceptual problem that you're having is wanting the program to somehow "know" that you want a quantity that is represented in bits to be output as megabytes. However, while the program knows that those units are convertible, there is no way for it to know that you want megabytes instead of gigabytes, kilobytes, or any other unit for which the conversion is defined. Thus, if you want specific output formatting, you need to do it yourself like I've done in outputDataCapacity... Hope this helps. Matthias