Ich gehe davon aus abs
und fabs
verhalte mich bei der Verwendung anders math.h
. Aber wenn ich nur cmath
und benutze std::abs
, muss ich std::fabs
oder verwenden fabs
? Oder ist das nicht definiert?
Ich gehe davon aus abs
und fabs
verhalte mich bei der Verwendung anders math.h
. Aber wenn ich nur cmath
und benutze std::abs
, muss ich std::fabs
oder verwenden fabs
? Oder ist das nicht definiert?
Antworten:
In C ++ ist die Verwendung immer ausreichend std::abs
. Es ist für alle numerischen Typen überladen.
In C abs
funktioniert nur mit ganzen Zahlen, und Sie benötigen fabs
Gleitkommawerte. Diese sind in C ++ (zusammen mit der gesamten C-Bibliothek) verfügbar, müssen jedoch nicht verwendet werden.
int
Version aus der C - Bibliothek gibt es Überlastungen für long
, float
, double
und long double
. Abschnitt 26.2.7 definiert auch eine Überlastung für complex
.
std::
und nur verwenden abs
, funktioniert Ihr Code unter Windows wie erwartet, verwendet jedoch die int
Version unter Linux, die unglaublich schwer zu debuggen sein kann.
Es ist immer noch in Ordnung, fabs
für double
und float
Argumente zu verwenden. Ich bevorzuge dies, weil es sicherstellt , dass das Verhalten für Gleitkomma-Eingaben gleich bleibt , wenn ich versehentlich das std::
ausziehe abs
.
Ich habe gerade 10 Minuten damit verbracht, genau dieses Problem zu debuggen, weil ich den Fehler gemacht habe, abs
anstelle von zu verwenden std::abs
. Ich nahm an, dass das using namespace std;
schließen würde, std::abs
aber es tat es nicht und verwendete stattdessen die C-Version.
Wie auch immer, ich glaube, es ist gut, fabs
anstelle von abs
Gleitkomma-Eingaben zu verwenden, um Ihre Absicht klar zu dokumentieren.
std::abs
scheint die Überlastung abs
beim Aufruf immer aufgerufen zu werden (und nicht die C-Version von ), abs
solange dies using namespace std;
am erklärt wird Anfang. Ich weiß allerdings nicht, ob dies compilerspezifisch ist.
Es gibt noch einen weiteren Grund, std::fabs
explizit für Gleitkomma-Eingaben zu empfehlen .
Wenn Sie vergessen, <cmath> einzuschließen, std::abs(my_float_num)
können Sie std::abs(int)
stattdessen sein std::abs(float)
. Es ist schwer zu bemerken.
"abs" und "fabs" sind nur für C ++ - Float-Typen identisch, wenn sie ohne mehrdeutige Überlastungsnachrichten übersetzt werden können.
Ich benutze g ++ (g ++ - 7). Zusammen mit der Verwendung von Vorlagen und insbesondere bei der Verwendung von mpreal gibt es Fälle mit harten "mehrdeutigen Überlastungs" -Nachrichten -abs(static_cast<T>(x))
wird nicht immer gelöst. Wenn abs mehrdeutig ist, besteht die Möglichkeit, dass Fabs wie erwartet funktionieren. Für sqrt habe ich keine so einfache Flucht gefunden.
Seit Wochen kämpfe ich hart mit C ++ "nicht existierenden Problemen". Ich aktualisiere ein altes C ++ - Programm auf C ++ 14, um mehr und bessere Vorlagen als bisher zu verwenden. Oft kann derselbe Vorlagenparameter ein beliebiger Standard-Float oder ein komplexer Typ oder ein Klassentyp sein. Long Double wirkte jedoch etwas vernünftiger als andere Typen. Alles funktionierte und ich hatte zuvor mpreal aufgenommen. Dann habe ich meinen Standard-Float-Typ auf mpreal gesetzt und eine Flut von Syntaxfehlern erhalten. Das führte zu Tausenden von mehrdeutigen Überlastungen, z. B. für abs und sqrt, und nach unterschiedlichen Lösungen. Einige benötigten überladene Hilfefunktionen, jedoch außerhalb einer Vorlage. Musste einzeln tausend Verwendungen von 0.0L und 1.0L durch den exakten Konstantentyp mit Zero oder One oder einem type_cast ersetzen - eine automatische Konvertierungsdefinition ist aufgrund von Mehrdeutigkeiten nicht möglich.
Bis Mai fand ich die vorhandenen impliziten Konvertierungen sehr schön. Aber viel einfacher wäre es ohne, und typsparende Konstanten mit sicheren expliziten type_casts für jeden anderen Standardkonstantentyp zu haben.