$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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.