Re: [Boost-users] [Units] implicit conversion of quantities

Steven Watanabe wrote:
In this particular case, I would suggest writing the function as a template and casting. In general you can write a forwarding overload that casts as appropriate.
Thanks Steven for the advice. I consulted Matthias Schabel off list to help figure out how to get this working. In case others have similar needs, I am attaching my modified 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 using namespace boost::units; using namespace std; // First version of showBondLength takes a specific quantity type (nanometers) std::ostream& showBondLength(quantity<nanometer_unit> len, std::ostream& os) { // This implementation could be compiled into a library. os << len << std::endl; } // Second version of showBondLength can take any length type, and casts it to // the specific type. The parameter type is a bit long winded for a public API // method, but not unreadable. template<class Y> std::ostream& showBondLength(quantity<unit<length_dimension, Y> > len, std::ostream& os) { // This (simple, forwarding) implementation must be fully defined in a header. return showBondLength( (quantity<nanometer_unit>)len, 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 (used to) fail to compile before templated version was added. // Users want implicit conversion here from angstroms to nanometers showBondLength(1.52 * angstrom, cout); showBondLength(len1, cout); showBondLength(len2, cout); showBondLength(len3, cout); showBondLength(len4, cout); // Conversion from meters works too showBondLength(3.0 * si::meters, std::cout); // Non-length quantities correctly fail to compile // showBondLength(3.0 * si::seconds, std::cout); return 0; } /* =================================== */
participants (1)
-
Christopher Bruns