Ich gehe davon aus absund fabsverhalte mich bei der Verwendung anders math.h. Aber wenn ich nur cmathund benutze std::abs, muss ich std::fabsoder verwenden fabs? Oder ist das nicht definiert?
Ich gehe davon aus absund fabsverhalte mich bei der Verwendung anders math.h. Aber wenn ich nur cmathund benutze std::abs, muss ich std::fabsoder 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 absfunktioniert nur mit ganzen Zahlen, und Sie benötigen fabsGleitkommawerte. Diese sind in C ++ (zusammen mit der gesamten C-Bibliothek) verfügbar, müssen jedoch nicht verwendet werden.
intVersion aus der C - Bibliothek gibt es Überlastungen für long, float, doubleund 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 intVersion unter Linux, die unglaublich schwer zu debuggen sein kann.
Es ist immer noch in Ordnung, fabsfür doubleund floatArgumente 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, absanstelle von zu verwenden std::abs. Ich nahm an, dass das using namespace std;schließen würde, std::absaber es tat es nicht und verwendete stattdessen die C-Version.
Wie auch immer, ich glaube, es ist gut, fabsanstelle von absGleitkomma-Eingaben zu verwenden, um Ihre Absicht klar zu dokumentieren.
std::absscheint die Überlastung absbeim Aufruf immer aufgerufen zu werden (und nicht die C-Version von ), abssolange dies using namespace std;am erklärt wird Anfang. Ich weiß allerdings nicht, ob dies compilerspezifisch ist.
Es gibt noch einen weiteren Grund, std::fabsexplizit 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.