Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloads of std::isnan and std::isinf for integral types

Cppreference mentions the overloads of std::isnan and std::isinf (and maybe others) for integral types. This makes the following call unambiguous:

std::isnan(1);

However, I cannot find any such overloads mentioned in the C++ Standard. I checked C++11 and the current draft, and there are only overloads for float, double, and long double.

As for compiler behavior, GCC and Clang both compile the code, but MSVC does not. Who is right? Where did the integral overload on cppreference come from?

like image 308
Daniel Langr Avatar asked May 29 '19 09:05

Daniel Langr


2 Answers

There is a paragraph at the end of the standard page for cmath:

For each set of overloaded functions within <cmath>, with the exception of abs, there shall be additional overloads sufficient to ensure:

2. Otherwise, if any argument of arithmetic type corresponding to a double parameter has type double or an integer type, then all arguments of arithmetic type corresponding to double parameters are effectively cast to double.

The integral overloads are mandatory, otherwise you would get ambiguous calls between the three floating point overloads, but how such overloads are implemented is unspecified.


Notice that other functions in the <cmath> header have correct overloads for integral types, e.g.,

std::atan(1)

calls the templated version double atan<int,void>(int).

like image 55
Holt Avatar answered Nov 20 '22 07:11

Holt


That's a synopsis, and there is a footnote

For each set of overloaded functions within , with the exception of abs, there shall be additional overloads sufficient to ensure:

...

  1. Otherwise, if any argument of arithmetic type corresponding to a double parameter has type double or an integer type, then all arguments of arithmetic type corresponding to double parameters are effectively cast to double.

which corresponds to the bool isnan( IntegralType arg ) description

A set of overloads or a function template accepting the arg argument of any integral type. Equivalent to (2) (the argument is cast to double).

like image 20
Useless Avatar answered Nov 20 '22 06:11

Useless