|
Boost Users : |
Subject: Re: [Boost-users] [Units] unary minus on units is counter intuitive (or a bug)
From: Matthias Schabel (boost_at_[hidden])
Date: 2010-11-30 14:14:05
> I found this counterintuitive result of applying the unary minus
> operator to a unit
>
> "- si::meter" is the same as "si::meter" (or any other unit).
>
> or worst
>
> std::cout << - si::meter*1. << std::endl; // prints 1*m
>
> i.e. the minus is explicitly ignored. The root of the problem is this
> curious line in boost/units/unit.hpp
I agree this is counterintuitive - the intent was that the unary operators should not affect units.
> a more intuitive result (but not completely elegant) could be attained
> by defining instead:
>
> template<class Dimension, class System>
> quantity<unit<Dim, System> >
> operator-(unit<Dim, System> const& u){
> return -1.*u;
> }
This would be inconsistent with library architecture...
> Note aside: Why would I need "minus units" in the first place? The
> original code that produced the confusion was
>
> - kB*T
>
> which appears commonly in physics. kB is the "atomic" unit of entropy/
> specific heat (atomic::heat_capacity) and T is a temperature quantity.
> This was parsed as
>
> (-kB)*T and then as kB*T
>
> i.e. the minus sign was ignored all together.
>
> In my opinion unary operator- should not be defined for units in the
> first place. The current definition only makes things worst, by
> creating a counter intuitive result AND making the fix conflict with
> the definition.
I think you're right that it is more correct for those operators to be undefined in this case.
Try the following and see if it works for you : in unit.hpp make the following change to lines 102-116 :
/// unit unary plus typeof helper
/// INTERNAL ONLY
//template<class Dim,class System>
//struct unary_plus_typeof_helper< unit<Dim,System> >
//{
// typedef unit<Dim,System> type;
//};
/// unit unary minus typeof helper
/// INTERNAL ONLY
//template<class Dim,class System>
//struct unary_minus_typeof_helper< unit<Dim,System> >
//{
// typedef unit<Dim,System> type;
//};
In quantity.hpp make the following change to lines 559-579 :
/// specialize unary plus typeof helper
/// INTERNAL ONLY
template<class Unit,class Y>
struct unary_plus_typeof_helper< quantity<Unit,Y> >
{
typedef typename unary_plus_typeof_helper<Y>::type value_type;
// typedef typename unary_plus_typeof_helper<Unit>::type unit_type;
typedef Unit unit_type;
typedef quantity<unit_type,value_type> type;
};
/// specialize unary minus typeof helper
/// INTERNAL ONLY
template<class Unit,class Y>
struct unary_minus_typeof_helper< quantity<Unit,Y> >
{
typedef typename unary_minus_typeof_helper<Y>::type value_type;
// typedef typename unary_minus_typeof_helper<Unit>::type unit_type;
typedef Unit unit_type;
typedef quantity<unit_type,value_type> type;
};
This should result in a compile error in your code at -kB*T which is certainly better than a silent error. If that works, we can commit the changes to trunk.
Matthias
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