Je suppose que abs
et je me fabs
comporte différemment lors de l'utilisation math.h
. Mais quand j'utilise juste cmath
et std::abs
, dois-je utiliser std::fabs
ou fabs
? Ou n'est-ce pas défini?
100
En C ++, il suffit toujours d'utiliser std::abs
; il est surchargé pour tous les types numériques.
En C, abs
ne fonctionne que sur les entiers et vous avez besoin fabs
de valeurs à virgule flottante. Ceux-ci sont disponibles en C ++ (avec toute la bibliothèque C), mais il n'est pas nécessaire de les utiliser.
int
version à partir de la bibliothèque C, il y a des surcharges pourlong
,float
,double
etlong double
. Le paragraphe 26.2.7 définit également une surcharge pourcomplex
.std::
et utilisez simplementabs
, votre code fonctionnera comme prévu sur Windows mais utilisera laint
version sous Linux, ce qui peut être incroyablement difficile à déboguer.Il est toujours possible d'utiliser
fabs
pourdouble
et desfloat
arguments. Je préfère cela car cela garantit que si j'enlève accidentellementstd::
leabs
, que le comportement reste le même pour les entrées à virgule flottante.Je viens de passer 10 minutes à déboguer ce problème même, à cause de ma propre erreur d'utiliser
abs
au lieu destd::abs
. J'ai supposé que leusing namespace std;
serait en déduire,std::abs
mais ce n'est pas le cas, et j'utilisais plutôt la version C.Quoi qu'il en soit, je pense qu'il est bon d'utiliser
fabs
au lieu deabs
pour les entrées en virgule flottante comme moyen de documenter clairement votre intention.la source
std::abs
semble toujours être invoquée (et non la version C deabs
) lors de l'appelabs
tant que celausing namespace std;
est expliqué au début. Je ne sais pas si c'est spécifique au compilateur.Il y a une autre raison de recommander
std::fabs
explicitement les entrées à virgule flottante.Si vous oubliez d'inclure <cmath>, vous
std::abs(my_float_num)
pouvez être à lastd::abs(int)
place destd::abs(float)
. C'est difficile à remarquer.la source
"abs" et "fabs" ne sont identiques que pour les types float C ++, lorsqu'ils peuvent être traduits sans messages de surcharge ambigus.
J'utilise g ++ (g ++ - 7). Avec l'utilisation de modèles et en particulier lors de l'utilisation de mpreal, il y a des cas avec des messages de «surcharge ambiguë» durs - ce
abs(static_cast<T>(x))
n'est pas toujours le cas. Lorsque les abdos sont ambigus, il y a des chances que les fabs fonctionnent comme prévu. Pour sqrt, je n'ai trouvé aucune évasion aussi simple.Depuis des semaines, je me bats dur sur C ++ "problèmes non existants". Je mets à jour un ancien programme C ++ vers C ++ 14 pour une meilleure utilisation des modèles qu'auparavant. Souvent, le même paramètre de modèle peut être un type flottant ou complexe standard ou un type de classe. Pourquoi jamais, long double a agi un peu plus sensible que les autres types. Tout fonctionnait, et j'avais déjà inclus mpreal. Ensuite, je définissais mon type float par défaut sur mpreal et j'ai eu un déluge d'erreurs de syntaxe. Cela a donné des milliers de surcharges ambiguës, par exemple pour les abdos et les sqrt, pleurant pour des solutions différentes. Certains avaient besoin de fonctions d'aide surchargées, mais en dehors d'un modèle. A dû remplacer individuellement un millier d'utilisations de 0.0L et 1.0L par le type de constante exact en utilisant Zero ou One ou un type_cast - définition de conversion automatique impossible en raison d'ambiguïtés.
Jusqu'en mai, j'ai trouvé très agréable l'existence des conversions implicites. Mais beaucoup plus simple ce serait sans aucun, et avoir des constantes de type enregistrer avec des types explicites sûrs dans n'importe quel autre type de constante standard.
la source