Boost logo

Boost Users :

Subject: Re: [Boost-users] [Units] conversion between double and millimeter
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2014-01-15 02:07:52


On 14/01/2014 22:46, Quoth Richel Bilderbeek:
> When I convert a double to a unit (e.g. meter) and back, this works as
> expected.
> When I convert a double to a prefixed unit (e.g. millimeter) and back,
> this fails to compile.
> The code below shows how I'd expect it to work.
> What do I overlook?
> Thanks, Richel Bilderbeek
>
> const double x_in_mm = 1.0;
> const Length x(x_in_mm * milli * meter);
> //This works as expected:
> const double x_again_in_m = x / meter;
> //Why doesn't this:
> const double x_again_in_mm = x / (milli * meter); //Fails

I don't know why that doesn't work (it seems logical to me).

But (until someone chimes in with a better one) a somewhat ugly
workaround would be:

const double x_again_in_mm = x / meter * conversion_factor(meter, milli
* meter);

If you're doing this a lot, you could define a to_mm(x) helper that does
the above, or you could define a new system with a millimeters base unit:

typedef scaled_base_unit<meter_base_unit, scale<10, static_rational<-3>
> > millimeter_base_unit;
// I don't know if there's a way to extract the scale from "milli"

typedef make_system<millimeter_base_unit>::type mm_system;
typedef unit<length_dimension,mm_system> millimeter_unit;
typedef quantity<millimeter_unit> LengthMM;

BOOST_UNITS_STATIC_CONSTANT(millimeters, millimeter_unit);

// this works
const double x_again_in_mm = LengthMM(x) / millimeters;

(There's probably a better way to do this.)

FWIW (for any Boost.Units developers watching), the error (in MSVC) with
the original form of the last line is:

   error C2440: 'initializing' : cannot convert from 'quantity<Unit,Y>'
to 'const double'
     with
     [
         Unit=unit<dimensionless_type,
heterogeneous_system<heterogeneous_system_impl<dimensionless_type,
dimensionless_type, list<scale_list_dim<scale<10, static_rational<3>>>,
dimensionless_type>>>>,
         Y=double
     ]
     No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called

ie. it looks like it correctly gets down to a dimensionless unit with a
scaling factor, but the conversion to double is only defined for a
"real" dimensionless unit, not one with a scaling factor attached.

You might want to file an issue in Trac to see if support can be added
for the original syntax you tried.


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