Портирование isnan на С++ 11

Когда я переключаю версию компилятора из gcc 4.6 в gcc 4.8, я получаю следующую ошибку Ошибка: вызов перегруженного "isnan (double)" неоднозначен.

Это связано с тем, что в С++ 11 есть объявления с различной функцией: C: int isnan (double) С++ 11: bool isnan (double)

из cpluplus:

  • В C это реализовано как макрос, возвращающий значение int. Тип x должен быть float, double или long double.
  • В С++ он реализуется с перегрузками функций для каждого типа с плавающей запятой, каждый из которых возвращает значение bool.

Как я могу это исправить?

Ответ 1

Хотя вы можете смягчить эту проблему, не говоря о using namespace std; везде, вы можете избежать этого, указав явное использование std::isnan:

#include <cmath>
#include <iostream>

int main()
{
  double x = ....;
  std::cout << std::boolalpha;
  std::cout << std::isnan(x) << std::endl;
}

Ответ 2

В C++ 11 не должно быть неоднозначности между функцией isnan C и C++. Он работает, как и ожидалось, даже с using namespace std.

Пожалуйста, убедитесь, что вы не используете и #include <math.h> и #include <cmath>. Только включить cmath.

В качестве альтернативы, возможно, в вашем проекте есть пользовательская isnan(double), или какой-то заголовок включает в себя "math.h".

Также обратите внимание, что если кто-то хочет написать универсальный код, неправильно использовать префикс 'std ::' в математических функциях, так как он нарушает поиск, зависящий от аргумента (ADL). (Поскольку стандарт C++ не позволяет вводить функции в пространство имен std ::)

Правильное использование isnan в универсальном коде - это using std::isnan; затем используйте просто isnan для переменных. В противном случае ваш код с пользовательскими типами с плавающей запятой, такими как произвольная точность, автоматическое дифференцирование и т.д., Не будет работать. Корень этого несоответствия заключается в том, что встроенные типы, такие как double, не находятся в пространстве имен std а функции, которые над ними работают.