
Boost : 
From: Dave Abrahams (abrahams_at_[hidden])
Date: 19991221 06:28:54
> From: Dave Abrahams [mailto:abrahams_at_[hidden]]
>> Speaking of friends, you could use the Barton & Nackmann
>> trick if partial ordering doesn't work in MSVC (does it?):
>
> Aha!!! This may be the missing piece of the puzzle. I was not aware of what
> "partial ordering" is. I'll look in the standard, but can you give a summary
> of the implications here, and I'll test it out?
Partial ordering is the mechanism for function templates which gives you the
equivalent of partial specialization for class templates. It's what would
help the compiler pick
template<class X> boost::rational<X> abs(boost::rational<X>);
instead of
template<class X> X abs(X);
if they were both available and you wrote:
boost::rational<int> r;
abs(r);
>>
>> template <class X>
>> struct rational_abs
>> {
>> friend abs(const X& x)
>> { using std::abs; return X(abs(x.numerator(), x.denominator()); }
>> };
>>
>> template <class T>
>> class rational : rational_abs<rational<T> >, ...
>
> Urg. I don't really see what this is doing. Could you elaborate? It seems to
> be forcing the lookup for friend abs() to be at class scope instead of
> namespace.
It's forcing the instantiation of this particular function at namespace
scope whenever the class is mentioned.
> It's also making the abs(rational) not be a template... I think.
right.
> (I'd never heard of the "Barton & Nackmann trick"  where did it come from?
> Are these sorts of tricks collected anywhere?)
Look up "Barton & Nackmann" at Amazon.com. There's a book on scientific
computing in C++. Personally, I learned of the trick from... (that's right)
Andy Koenig!
> My brain is *really* hurting...
Don't feel bad; for a long time I thought that's what "Koenig lookup" meant!
>> Try the B&N trick described above. That should solve a lot of
>> problems by not requiring so much template smarts from the compiler. This
>> would simply generate a single abs() overload for each version of
>> rational. Hmm, though to get abs() into the global namespace you might
> need to
>> put rational_abs there, too. Maybe you need to call it
> boost_rational_abs__()
>> for MSVC's purposes.
>
> I think that not requiring so much template smarts is the key here.
More from us, maybe less from the compiler (if the compilers are busted) ;)
Dave
P.S. Extra bonus points if you can find a good way for abs() to be imported
from the global namespace back into boost ;)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk