Boost logo

Boost Users :

Subject: Re: [Boost-users] [units] unit conversion on construction in relation to argument passing
From: Noah Roberts (roberts.noah_at_[hidden])
Date: 2011-03-25 19:06:13


On 3/25/2011 10:40 AM, alfC wrote:
>
>
> On Mar 25, 9:46 am, Matthias Schabel<bo..._at_[hidden]> wrote:
>>>> nice! But for some reason I believe this would work for argument
>>>> functions
>>
>>>> double f(quantity<si::length> v){ return 1.;}
>>>> ...
>>>> quantity<cgs::lengh> A = 4.*cgs::centimeter
>>>> f(A); // doesn't work! not matching function
>>
>>>> why is this? isn't the argument of the call a sort of construction
>>>> argument for the function argument, or is more like a plain
>>>> assignment. Is there a way to force the automatic conversion of the
>>>> function call.
>>
>>>> Or I am forced to use this other long call?
>>
>>>> f(quantity<si::length>(A));
>>
>>> Yes. The constructor is explicit.
>>
> thanks for the clarification
>>
>> Or you can write it as a template function that takes any argument that is a quantity of length :
>> [...code...]
>
> Thank you for the suggestion, the problem is that a nice looking
> function such as
>
> void f(
> quantity<volume> v,
> quantity<temperature> t,
> quantity<length> l
> ){
> ... use v, l, t in a given controlled set of units
> }
>
> transfroms into this mess,
>
> template<
> class VolumeUnit,
> class TemperatureUnit,
> class LengthUnit
>> void f(
> quantity<VolumeUnit> v_,
> quantity<TemperatureUnit> t_,
> quantity<LengthUnit> l_
> ){
> quantity<volume> v(v);
> quantity<temperature> t(t_);
> quantity<length> l(l_);
> ... use v, l, t in a given controlled set of unit
> }
>
> just to obtain the same effect. and that without even static asserting
> that XXXUnit is_unit.

Not usually. If your equations are dimensionally coherent, and not
empirical, you can generally do without a lot of what you just showed.
For example, one might be tempted to write the head/pressure conversion as:

quantity<si::pressure> head_to_press( quantity<si::length> head
                                     , quantity<si::mass_density> den )
{
   quantity<si::acceleration> g = 9.80665 * si::meters_per_second_squared
   return head * den * g;
}

All you really need to do though is:

template < typename System, typename T >
quantity< unit<pressure_dimension, T >
head_to_press( quantity< unit<length_dimension, System>, T> head
              , quantity< unit<mass_density_dimension, System>, T> den )
{
   quantity< unit<acceleration_dimension, System>, T> g(9.8066 *
si::meters_per_second_squared);

   return head * den * g;
}

The only part you have to do explicit conversions on is your constants.

Of course, when dealing with empirical equations you've got a different
thing going on. More often than not you have to break out of the units
anyway and use the "unsafe" operations like ::from_value.


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