SFINAE std :: isfinite and similar functions using std :: is_arithmetic

I just ran into a compilation failure when porting some code from VS2013 to GGC 4.9 and Clang 3.5 (using libC ++). Code Essence

#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 that the isfinite call isfinite not compile, because the isfinite funtion function in cmath has a return type declared as:

 typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type 

and because Foo not is_arithmetic , isfinite is removed from the overload set. The same applies to isfinite friends like isnan . So my question is whether this is expected.

Does the standard isfinite to these arguments with functions such as isfinite , such as actually directly double or float , in contrast to the fact that they are implicitly converted to them?

Also, I'm a little unsure why std::is_arithmetic not std::is_floating_point , isn't is_arithmetic implies isfinite for integers?

As an additional question, what is the best way to specify a constraint such as is_convertible_to_floating_point?

+5
source share
1 answer

ยง26.8 [c.math] / p10-11:

The classification / comparison functions behave in the same way as 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 three types of floating point, as shown below:

 // other functions omitted bool isfinite(float x); bool isfinite(double x); bool isfinite(long double x); 

In addition, there must be additional overloads sufficient to ensure:

  • If any arithmetic argument corresponding to a double parameter is of type long double , then all arithmetic arguments corresponding to double parameters are effectively displayed in long double .
  • Otherwise, if any arithmetic argument corresponding to the double parameter is of the double type or an integer type, then all arithmetic arguments corresponding to the double parameters are effectively transferred to double .
  • Otherwise, all arithmetic arguments corresponding to double parameters are of type float .

I would set the error in libC ++.

+5
source

Source: https://habr.com/ru/post/1208507/


All Articles