Boost logo

Boost Users :

Subject: [Boost-users] [Units] implicit conversion of quantities
From: Christopher Bruns (cmbruns_at_[hidden])
Date: 2009-03-03 14:04:59


Kudos on the excellent implementation of the Boost.Units library. I
am also very grateful for the extremely timely help I have got in the
past from the principal authors Matthias Schabel and Steven Watanabe.

Is there any way to force implicit conversion of Angstrom quantities
to nanometer quantities in assignment and method calls using
Boost.Units? I would appreciate any suggestions on how to get the
final three method calls in the attached program to compile.

I suppose I could overload the showBondLength() method in this example
to take both types. I think I would prefer implicit conversion, if
that is possible.

I am using boost from subversion revision 51579, from March 3, 2009.

--Chris Bruns

/* =========== begin test program ========== */

#include <boost/units/systems/si.hpp>
#include <boost/units/base_units/metric/angstrom.hpp>
#include <iostream>

namespace boost { namespace units
{
    typedef metric::angstrom_base_unit::unit_type angstrom_unit;
    BOOST_UNITS_STATIC_CONSTANT(angstrom, angstrom_unit);

    typedef scaled_base_unit<
            si::meter_base_unit,
            scale<10, static_rational<-9> >
> nanometer_base_unit;
    typedef nanometer_base_unit::unit_type nanometer_unit;
    BOOST_UNITS_STATIC_CONSTANT(nanometer, nanometer_unit);

} } // namespace boost::units

// No permutation of BOOST_UNITS_DEFAULT_CONVERSION macro has
// *ever* had a measurable effect in my hands
BOOST_UNITS_DEFAULT_CONVERSION(
    boost::units::angstrom_unit,
    boost::units::nanometer_unit
);

using namespace boost::units;
using namespace std;

ostream& showBondLength(
        quantity<nanometer_unit> len,
        std::ostream& os)
{
    os << len << endl;
    return os;
}

int main()
{
    // These constructors all work; conversions are automatic
    quantity<nanometer_unit> len1( 0.152 * nanometer );
    quantity<angstrom_unit> len2( 1.52 * angstrom );
    quantity<nanometer_unit> len3( 1.52 * angstrom );
    quantity<angstrom_unit> len4( 0.152 * nanometer );

    // These three calls are OK, nanometer quantity is passed
    showBondLength(0.152 * nanometer, cout);
    showBondLength(len1, cout);
    showBondLength(len3, cout);

    // Explicit casts to nanometer are OK for angstrom quantities...
    // but yuck
    showBondLength( (quantity<nanometer_unit>) (1.52 * angstrom), cout );
    showBondLength( (quantity<nanometer_unit>) len2, cout );
    showBondLength( (quantity<nanometer_unit>) len4, cout );

    // These all fail to compile. Users want implicit conversion here
    showBondLength(1.52 * angstrom, cout);
    showBondLength(len2, cout);
    showBondLength(len4, cout);
}

/* =========== end test program =========== */


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net