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 todouble
parameters are effectively cast tolong double
.- Otherwise, if any arithmetic argument corresponding to a
double
parameter has typedouble
or an integer type, then all arithmetic arguments corresponding todouble
parameters are effectively cast todouble
.- Otherwise, all arithmetic arguments corresponding to
double
parameters 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