I just ran into a compilation failure when porting some code from VS2013 to GGC 4.9 and Clang 3.5 ( using libc++ ). The gist of the code is
#include <cmath>
struct Foo
{
    operator double() const { return( 101.0 ); } // Implicit conversion to double
};
int main( int, char** )
{
    Foo foo;
    std::exp( foo );      // Compiles
    std::isfinite( foo ); // Does not
    return( 0 );
}
I believe the isfinite call does not compile because the isfinite funtion in cmath has return type declared as:
typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
and because Foo is not is_arithmetic, isfinite gets removed from the overload set. The same is true of friends of isfinite like isnan. So my question is whether this is expected.
Does the standard require that arguments to functions like isfinite as actually directly double or float as opposed to being implicitly convertible to them?
Also I'm a bit unsure why is std::is_arithmetic not std::is_floating_point, doesn't is_arithmetic imply isfinite on integers?
As an extra question what is the best way of specifying a constraint like is_convertible_to_floating_point?
§26.8 [c.math]/p10-11:
The classification/comparison functions behave the same as the C macros with the corresponding names defined in 7.12.3, Classification macros, and 7.12.14, Comparison macros in the C Standard. Each function is overloaded for the three floating-point types, as follows:
// other functions omitted bool isfinite(float x); bool isfinite(double x); bool isfinite(long double x);Moreover, there shall be additional overloads sufficient to ensure:
- If any arithmetic argument corresponding to a double parameter has type
 long double, then all arithmetic arguments corresponding todoubleparameters are effectively cast tolong double.- Otherwise, if any arithmetic argument corresponding to a
 doubleparameter has typedoubleor an integer type, then all arithmetic arguments corresponding todoubleparameters are effectively cast todouble.- Otherwise, all arithmetic arguments corresponding to
 doubleparameters have typefloat.
I'd file a bug against libc++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With