Est isnan dans le std:: espace de noms? Plus en général, quand on est std:: nécessaire, en option ou à éviter?
Avec Mingw 4.7.2, j'ai une bibliothèque qui ne compile pas en raison d'un appel à isnan
.
Le compilateur dit "tout ira bien" si j'utilise std::isnan
, et en effet j'ai réussi à compiler mon fichier.
Mais si je coche ici (Edit: mais peut-être que je devrais avoir vérifié aussi ici 🙂 ), le std::
ne semble pas être nécessaire. Si je l'ajoute, le fichier de portable?
Plus en général, pour chaque cas, est-il une façon générale, à comprendre lors de la mise std::
est nécessaire (pour la portabilité), en option ou à éviter?
Modifier
En effet parmi les origines du problème, c'est qu'il y a plusieurs en-tête des inclusions, et certains en-têtes inclus comprennent <cmath>
, alors que ce fichier cpp essaie de l'inclure <math.h>
(quand <cmath>
a déjà été inclus).
- Ne pas vérifier, vérifier ici.
- Donc, fondamentalement, en C++98 ce n'existait pas, et on pouvait l'avoir qu'en l'empruntant à C! C'est intéressant!
- Non, il a toujours été la façon dont il est. Ce lien devrait simplement vous montrer qu'il y a une grande
std::
devant le nom de la fonction. Par coïncidence, cette fonction particulièreisnan
est uniquement pris en charge avec C++11 et n'existent pas en C++98 à tous (même dans l'en-tête C, qui a été le C89/90-tête et de ne pas le C99 en-tête C++11 utilise). Ainsi, dans une manière que vous pourriez emprunter à partir de C, mais pas à partir de la C inclus avec le C++, mais à partir d'une réelle C99 (même si ça doit être un mélange étrange à l'époque).
Vous devez vous connecter pour publier un commentaire.
Ça dépend de l'en-tête à inclure. Si vous incluez l'en-tête C
<math.h>
(qui est une partie de C++, mais marqué comme obsolète), vous pouvez utiliser le sans réserve les fonctions C, commeisnan
. Si vous avez d'autre part d'inclure l'en-tête C++<cmath>
, vous n'êtes garanti qu'il apporte toutes les fonctions de<math.h>
dans lestd
espace de noms et vous devez donc le qualifier correctement, commestd::isnan
(ou utiliser une sorte deusing
la directive). Malheureusement, l'application est permis mais pas nécessaire à apporter à ces fonctions, en l'espace de noms global, trop, y compris lorsque<cmath>
(et donc il est l'un des nombreux "fonctionne sur ma machine"-incidences de C++ et de la raison pour laquelle beaucoup de gens à écrire du code comme vous avez juste essayé de compiler sans succès).Donc, pour résumer: Soit inclure
<math.h>
et l'utilisationisnan
ou inclure<cmath>
et l'utilisationstd::isnan
, tout le reste est non-portable. Bien sûr, tout cela s'applique à tous les autres d'en-tête C et sa version C++, trop.EDIT: Il convient de noter toutefois que cette fonction particulière
isnan
est uniquement pris en charge depuis C++11 et n'était pas disponible en C++98 à tous (ce qui peut être une partie de votre confusion). Mais cela ne changera rien à cette situation parce que le C++98 ni<cmath>
ni<math.h>
(qui était à l'C89/C90-tête à l'époque, et pas le C99 en-tête C++11 comprend) a cette fonction, car ils sont toujours en parfaite synchronisation. Donc, ce que cette bibliothèque à partir de votre question peut-être essayé était d'utiliser le C++98, tout en tenant laisnan
fonction à partir d'un autre C99 mise en œuvre (ce qui n'est pas une très bonne idée, car il pourrait entrer en conflit avec le C89/C90 parties de l'implémentation C++, n'a même jamais essayé ce bien).std::
tous sur la place, préférez le C++ en-têtes, tout de même). Mais vous devez rester cohérent bien sûr, sinon il vous arrive de faire l'expérience de ces stangeties comme vous avez fait.<cmath>
ne devrait même pas être là en C++98... Et la seule isnan pour C++98 dans le obsolète<math.h>
, qui doit être appelée sansstd::
. Donc, pour être portable, c'est... impossible 🙂 à moins de mettre un peu lourd de compilation conditionnelle.<cmath>
est l'en-tête C++, alors que<math.h>
est le C de l'en-tête inclus avec la bibliothèque C++.<math.h>
n'a pasisnan
soit, il n'y a vraiment aucune forme deisnan
à tous en C++ pré-11. Dans ce cas, un portableisnan
n'est possible que par la transmission des textes de toute façon.C n'a pas de notion d'espaces de noms. Lorsque vous écrivez
#include <math.h>
tous les noms déclarés dans l'en-tête d'aller dans l'espace de noms global, et vous avez besoin d'écrireisnan
.C++ a des espaces de noms. Encore, lorsque vous écrivez
#include <math.h>
tous les noms déclarés dans l'en-tête d'aller dans l'espace de noms global, et vous avez besoin d'écrireisnan
, tout comme en C.En outre, lorsque vous écrivez
#include <cmath>
tous les noms déclarés dans l'en-tête d'aller dans l'espace de nomsstd
, et vous avez besoin d'écrirestd::isnan
.De plus, C++ implémentations sont permis aussi aller dans l'autre sens, avec
#include <math.h>
de mettre les noms enstd
ainsi que dans l'espace de noms global, et avec#include <cmath>
mettre les noms dans l'espace de noms global ainsi que dansstd
. Ne comptez pas sur ce; code n'est pas portable. C'est une concession à des réalisateurs pour faciliter les choses; ce qu'il signifie vraiment, c'est que si vous utilisez#include <cmath>
vous ne pouvez pas supposer qu'il n'y aura pas deisnan
dans l'espace de noms global et que si vous utilisez#include <math.h>
vous ne pouvez pas supposer qu'il n'y aura pas deisnan
dansstd
.std
et de l'espace de noms global.C'est parce que
isnan
est à partir de C. à l'Aide de différents type deinclude
va conduire à des résultats différents. Prendreisnan
d'en-tête C<math.h>
comme un exemple:Si vous utilisez
#include <cmath>
, il sera mis dans lestd
espace de noms.Si vous utilisez
#include <math.h>
, elle sera placée dans l'espace de noms global.C++11 D. 5 bibliothèque standard C-têtes