| Home | Libraries | People | FAQ | More

### 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>`.