Boost logo

Boost :

From: Paul Moore (gustav_at_[hidden])
Date: 1999-12-14 18:57:46

I am still struggling with implementing abs() for rationals.

To summarise, I have

    template <typename IntType> class rational {
        friend rational abs (const rational &);

    template <typename IntType>
    inline rational<IntType> abs (const rational<IntType> &r)
        // point (1)
        return rational<IntType>(abs(r.num), r.den);

Now, Koenig Lookup should find the friend abs when abs(r) is called with a
rational. But what about the *definition* of abs()? I use abs() here, as using
std::abs precludes IntType being a user-defined type. But to do this, I need to
add "using std::abs;" at point (1).

Now we have an issue - the using declaration needs to be protected by
BOOST_NO_STDC_NAMESPACE from <boost/config.hpp>.

But even with this, MSVC *still* has a problem - it fails to look for ::abs
[[ie, std::abs]] when compiling abs(rational). The error is

..\..\boost/rational.hpp(248) : error C2784: 'class boost::rational<IntType>
__cdecl boost::abs (const class boost::rational<IntType> &)' : could not deduce
template argument for 'const class boost::rational<IntType> &' from 'const int'
        rational_example.cpp(61) : see reference to function template
instantiation 'class boost::rational<int> __cdecl boost::abs(const class
boost::rational<int> &)' being compiled

which seems to imply that MSVC isn't looking for the "normal" abs(int).

Can anybody suggest a workaround for this??? I ought to say that MSVC
compatibility is an absolute requirement - I use MSVC, so I'm not going to write
code which doesn't work with it (even allowing for the fact that I'm not sure
exactly what the standard would mandate on this issue!).

I'm thinking that I might be reduced to replacing abs(n) with (n < 0 ? -n : n).
This is OK, as we are requiring IntType to have "integer-like" semantics, but it
blows any hope of optimisation for a user-defuined IntType right out of the
water. (If someone can offer me a suitable implementation for
standard-conforming compilers, I'd be willing to put the hack in an ifdef

All assistance gratefully accepted :-) I attach the header and test program.


Boost list run by bdawes at, gregod at, cpdaniel at, john at