Проблема может быть воспроизведена с помощью:
#define __CORRECT_ISO_CPP11_MATH_H_PROTO 1
#include <cmath>
int main()
{
float v;
std::fpclassify(v);
}
Стандарт C ++ 11 (N3337) определяет 3 перегрузки для std::fpclassify
для 3 типов с плавающей запятой (без constexpr
).
Код не компилируется, поскольку заголовок cmath
в этих версиях gcc содержит (псевдокод):
#include <math.h>
#undef fpclassify
#if __cplusplus >= 201103L
#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
constexpr int fpclassify(float __x) {.....}
constexpr int fpclassify(double __x) {.....}
constexpr int fpclassify(long double __x) {.....}
#endif
template<typename _Tp>
constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type
fpclassify(_Tp __x)
{
Это означает, что std::fpclassify
найден толькоцелочисленным аргументом.(Я полагаю, что целочисленная перегрузка должна удовлетворять общему математическому требованию, что целочисленные аргументы функций с плавающей запятой должны вызывать перегрузку double
).
Я нашел соответствующую фиксацию для libstdc ++ .В комментарии предлагается, чтобы этот макрос определялся только в том случае, если math.h
уже предоставил три перегрузки fpclassify
для трех типов с плавающей запятой.
Код autoconf для libstdc ++ проверяет существующую систему math.h
и выдает этот макрос, если он уже определил три перегрузки fpclassify
.
Если вы находитесь в реализации, где math.h
не предоставляет перегрузок, поэтому вы не должны использовать этот макрос, иначе вы сделаете вашу реализацию не соответствующей.