Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Overloading template functions with float128_t

An artifact of providing C++ standard library support for quadmath may mandate the inclusion of <boost/cstdfloat.hpp> before the inclusion of other headers.

Consider a function that calls fabs(x) and has previously injected std::fabs() into local scope via a using directive:

template <class T>
bool unsigned_compare(T a, T b)
{
   using std::fabs;
   return fabs(a) == fabs(b);
}

In this function, the correct overload of fabs may be found via argument-dependent-lookup (ADL) or by calling one of the std::fabs overloads. There is a key difference between them however: an overload in the same namespace as T and found via ADL need not be defined at the time the function is declared. However, all the types declared in <boost/cstdfloat.hpp> are fundamental types, so for these types we are relying on finding an overload declared in namespace std. In that case however, all such overloads must be declared prior to the definition of function unsigned_compare otherwise they are not considered.

In the event that <boost/cstdfloat.hpp> has been included after the definition of the above function, the correct overload of fabs, while present, is simply not considered as part of the overload set. So the compiler tries to downcast the float128_t argument first to long double, then to double, then to float; the compilation fails because the result is ambiguous. However the compiler error message will appear cruelly inscrutable, at an apparently irrelevant line number and making no mention of float128: the word ambiguous is the clue to what is wrong.

Provided you #include <boost/cstdfloat.hpp> before the inclusion of the any header containing generic floating point code (such as other Boost.Math headers, then the compiler will know about and use the std::fabs(std::float128_t) that we provide in #include <boost/cstdfloat.hpp>.


PrevUpHomeNext