|
Boost : |
From: helmut.zeisel_at_[hidden]
Date: 2001-08-09 09:49:29
In some cases, it might be useful to
overwrite the default implementation of rational_cast
(e.g. if the numerator or the denominator
is not represantable as double, but their quotient is).
Trying this, GCC 3.0 gives the following diagnosis:
#include <boost/rational.hpp>
class A{};
namespace boost
{
template<typename T> T rational_cast(const rational<A>& a){return
0;}
};
int main()
{
boost::rational<A> a;
double d=boost::rational_cast<double>(a);
return 0;
}
c++ main.cxx
main.cxx: In function `int main()':
main.cxx:10: call of overloaded
`rational_cast(boost::rational<A>&)' is ambiguous
/usr/local/include/boost/rational.hpp:501:
candidates are: T
boost::rational_cast(const boost::rational<IntType>&)
[with T = double, IntType = A]
r.cxx:5: T boost::rational_cast(const boost::rational<A>&)
[with T = double]
As I understand, GCC 3.0 is right,
because the standard is somewhat unclear in that respect:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#200
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#214
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#250
A possible workaround for that problem could be
to add some traits for rational_cast,
e.g. by the following change in rational.hpp:
struct default_cast_tag{};
template<typename I> struct rational_traits
{
typedef default_cast_tag cast_tag;
};
template <typename T, typename IntType>
inline T rational_cast(const rational<IntType>& src,default_cast_tag)
{
return static_cast<T>(src.numerator())/src.denominator();
}
template<typename T, typename IntType>
inline T rational_cast(const rational<IntType>& src)
{
return rational_cast<T>(src,rational_traits<IntType>::cast_tag());
}
Helmut
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk