Réponses:
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 pour long
, float
, double
et long double
. Le paragraphe 26.2.7 définit également une surcharge pour complex
.
std::
et utilisez simplement abs
, votre code fonctionnera comme prévu sur Windows mais utilisera la int
version sous Linux, ce qui peut être incroyablement difficile à déboguer.
Il est toujours possible d'utiliser fabs
pour double
et des float
arguments. Je préfère cela car cela garantit que si j'enlève accidentellement std::
le abs
, 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 de std::abs
. J'ai supposé que le using 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 de abs
pour les entrées en virgule flottante comme moyen de documenter clairement votre intention.
std::abs
semble toujours être invoquée (et non la version C de abs
) lors de l'appel abs
tant que cela using 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 à la std::abs(int)
place de std::abs(float)
. C'est difficile à remarquer.
"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.