Frage zur richtigen Verwendung des Konvertierungsoperators
-
Hallo, ich schreibe gerade eine Klasse, die mit besonderen Zahlen arbeitet. Diese Zahlen sollen auch in die integrierten typen umgewandelt werden können. Im Moment löse ich das folgendermaßen:
class Zahlen { operator bool () const; operator short () const; operator int () const; operator long () const; operator unsigned short () const; operator unsigned int () const; operator unsigned long () const; operator std::string () const; operator float () const; operator double () const; operator long double () const; };Das Problem dabei ist folgendes: Die typen "long long" und alle Fließkommatypen (also float, double und long double) als unsigned gibt es zB. im gcc compiler nicht (im ms compiler schon). Dadurch ist der Code wenig portabel. Ich habe mir jetzt diese Lösung überlegt
class Zahlen { operator bool () const; //true bei != 0 template <typename T>operator T () const { T tmp; std::stringstream Str; Str << *this; //den überladenen << Operator vorausgesetzt Str >> tmp; return tmp; } }Was haltet ihr von der Methode? Gibt es etwas zu verbessern? Oder vielleicht sogar einen besseren Weg?
-
Konvertierer schrieb:
...Das Problem dabei ist folgendes: Die typen "long long" und alle Fließkommatypen (also float, double und long double) als unsigned gibt es zB. im gcc compiler nicht (im ms compiler schon). ...
Ich würde sagen: Dein Problem ist, dass Du Typen verwendest, die nicht standardkonform sind.

Also prinzipiell finde ich die Implementierung nicht schlecht ... aber den Grundansatz, dass Deine Klasse implizit in alles mögliche konvertiert werden kann.
Das birgt jede Menge Fehlerpotential für den Anwender ... lieber explizit machen.
Auch würde ich als Anwender mich fragen, was ich "verliere", wenn ich statt Deines Typen dann mit einem float oder unsigned short oder .... weiterrechne.Und letztlich: Mit Deinem Ansatz kann ich natürlich Deinen Typen auch auf std::string und alles Mögliche Andere "casten".
Gruß,
Simon2.
-
Konvertierer schrieb:
Oder vielleicht sogar einen besseren Weg?
Wofür denn?
Was soll das alles?Das sind Operatoren für implizite Konvertierungen. Du solltest Dir vorher ganz genau überlegen, ob Du die wirklich brauchst und ob es ein Problem geben könnte, wenn sie in Situationen (implizit) benutzt werden, ohne das der Benutzer das vielleicht wollte oder überhaupt mit gerechnet hat.
Gruß,
SP
-
1. Der GCC kennt die Typen
long long,float,double,long double. Bis auflong longsind auch alle im C++ Standard enthalten.
2. Auf Konvertierungsoperatoren sollte man so oft wie möglich verzichten, da sie implizit sind. Deine Vorgehensweise ist äusserst kritisch und seeeeeehr fehleranfällig.
3. Verwende toXYZ Funktionen. Halte dich zudem an die Typen, welche im Standard gegeben sind. Dann geht alles ohne Probleme.Edit: Ach mist, wurde kurz abgelenkt und habe nicht auf absenden geklickt. Tja, nun bin ich etwas zu spät

Grüssli
-
Hatte mir schon gedacht, dass es mehr Nachteile als Vorteile dadurch gibt (Wahrscheinlich wird man irgendwann mit Mehrdeutigen Funktionsaufrufen oder ähnlichem konfrontiert). Mein Ziel war es, dass man die Klasse genau so benutzen kann, wie die integrierten typen (die sich ja mehr oder weniger auch alle ineinander konvertieren lassen).
-
Dravere schrieb:
...
long double. Bis auflong longsind auch alle im C++ Standard enthalten....long doubleauch?
Wäre nicht das erste Mal, dass ich auf eine mir bislang unbekannte Ecke im C++-Std hingewiesen würde.Konvertierer schrieb:
...die integrierten typen (die sich ja mehr oder weniger auch alle ineinander konvertieren lassen).
Ehrlich gesagt: Das finde ich in viel mehr Zusammenhängen nervig als nützlich.
Gruß,
Simon2.
-
Simon2 schrieb:
long doubleauch?Klar:
C++ Standard 14882:2003 - 3.9.1 Fundamental Types - Abschnitt 8There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template numeric_limits (18.2) shall specify the maximum and minimum values of each arithmetic type for an implementation.
Habe ich persönlich aber auch erst relativ spät endgültig bemerkt. Allerdings ist zum Beispiel auf dem MSVC
long doublenur eintypedefaufdouble.Grüssli
-
ich meinte in meinem Eingangspost folgendes::
//funktioniert bei MS compiler und gcc float double long double //funktioniert NUR bei MS Compiler: unsigned float unsigned double unsigned long double //und natürlich long long und unsigned long long
-
Konvertierer schrieb:
ich meinte in meinem Eingangspost folgendes::
//funktioniert bei MS compiler und gcc float double long double //funktioniert NUR bei MS Compiler: unsigned float unsigned double unsigned long double //und natürlich long long und unsigned long longLoL? Welcher Kompiler? Das ist weder Standard C++ noch eine MSVC Erweiterung. Also bei meinem MSVC 2008 funktioniert dies nicht und es gibt einen Kompilerfehler. In der MSDN konnte ich dazu auch nichts finden. Bei Floating-Point Typen gibt es keine
unsignedVarianten, punkt.unsigned long longgibt es, soweit mir bekannt ist, auch unter dem GCC.Grüssli
-
Dravere hat recht, war mein Fehler: unsigned double kompiliert zwar mit MSVC, es gibt aber eine Warnung, dass unsigned keinen Effekt hat.
-
Simon2 schrieb:
Konvertierer schrieb:
...die integrierten typen (die sich ja mehr oder weniger auch alle ineinander konvertieren lassen).
Ehrlich gesagt: Das finde ich in viel mehr Zusammenhängen nervig als nützlich.
So möge er denn Klassen bauen, die die Typen kapseln und explizite Konstruktoren haben. Oder Java verwenden...

Dravere schrieb:
Habe ich persönlich aber auch erst relativ spät endgültig bemerkt. Allerdings ist zum Beispiel auf dem MSVC
long doublenur eintypedefaufdouble.Ein
typedefstelle ich mir hier schwierig vor...
Zudem ist es auch falsch.long doubleist ein eigenständiger Typ, der sich unter MSVC++ allerdings gleich wiedoubleverhält.
-
Dravere schrieb:
Simon2 schrieb:
long doubleauch?Klar:
...Danke!
Da merkt man aber auch, dass ich NIE Fließkmmatypen verwende. Brauche ich fachlich nicht wirklich und ist mir mit Näherungsproblemen&Co zu problematisch.
(Womit ich natürlich nicht sagen will, dass sie nicht in anderen Umfeldern sinnvoll/besser/optimal sein können)Man lernt nie aus.
Gruß,
Simon2.
-
Nexus schrieb:
Simon2 schrieb:
Konvertierer schrieb:
...die integrierten typen (die sich ja mehr oder weniger auch alle ineinander konvertieren lassen).
Ehrlich gesagt: Das finde ich in viel mehr Zusammenhängen nervig als nützlich.
So möge er denn Klassen bauen, die die Typen kapseln und explizite Konstruktoren haben. Oder Java verwenden... ;)...
Falls Du mit "ihm" mich meinst, verstehe ich nicht, warum.
a) Allenthalben gilt es als guter Stil, mit impliziter Konvertierung so sparsam wüe möglich umzugehen -
b) aber zwischen char/int/float/double/short/long geht alles irgendwie.... und genau mit den Problemen, die zu a) führen.Gruß,
Simon2.
-
Simon2 schrieb:
Falls Du mit "ihm" mich meinst, verstehe ich nicht, warum.
Ja, ich meinte dich. Sorry für die etwas merkwürdige Formulierung.

Klar, implizite Umwandlungen sollten eigentlich nicht allzu oft vorkommen. Ich meinte eher, wenn du auf Nummer Sicher gehen willst, weil du dir zum Beispiel Genauigkeitsfehler nicht leisten kannst. Da könnte es sich eventuell schon lohnen, die Typsicherheit durch Klassen zu verstärken. Besser ists natürlich, du achtest dich ein wenig. Aber ich weiss ja nicht, vielleicht hast du noch mit anderem Code zu tun, und bei vielen verschiedenen Typen kann man schnell mal die Übersicht verlieren.
Mein Satz sollte übrigens mehr als Randbemerkung dienen, komplett ernst gemeint war der nicht...

-
Nexus schrieb:
Dravere schrieb:
Habe ich persönlich aber auch erst relativ spät endgültig bemerkt. Allerdings ist zum Beispiel auf dem MSVC
long doublenur eintypedefaufdouble.Ein
typedefstelle ich mir hier schwierig vor...
Zudem ist es auch falsch.long doubleist ein eigenständiger Typ, der sich unter MSVC++ allerdings gleich wiedoubleverhält.
Ja, dastypedefdürfte schwierig werden. Ich wollte allerdings damit nur ausdrücken, dass die Typen gleich sind. Allerdings werden sie vom Kompiler als zwei unterschiedliche Typen gehandhabt. Diese Formulierung mit demtypedefwar vielleicht ein wenig unglücklich gewählt.Grüssli
-
Nexus schrieb:
...Da könnte es sich eventuell schon lohnen, die Typsicherheit durch Klassen zu verstärken. ...
Schöner wär's halt, wenn ich mich nicht "im Sonderfall achten" oder extra Konstrukte drumherumbasteln müsste. Die Übersicht verliere ich persönlich eher durch die vielen möglichen impliziten Konvertierung der elementaren Typen. Ruckzuck wird da eine float-Funktion aufgerufen, wo ich eigentlich mit double rechnen möchte. Oder ich will unschuldigerweise eine nicht vorhandene Funktion definieren und bekomme einen "ambiguious error, weil es bereits eine gleichnamige Funktion für einen konvertierbaren Typen gibt ...
Aber egal: War ja auch nur Randbemerkung.Gruß,
Simon2.