Ich möchte in der main-Funktion mit "cout" das Objekt "today" auf den
Bildschirm ausgeben, aber ich erhalte folgende Fehlermeldungen:
>> Fehler E0349: Kein "<<"-Operator stimmt mit diesen Operanden überein.>> Fehler C2679: Binärer Operator "<<": Es konnte kein Operator gefunden werden,
der einen rechtsseitigen Operanden vom Typ "Month" akzeptiert (oder keine
geeignete Konvertierung möglich)
Beide Fehler beziehen sich auf die Funktion mit der Operator Überladung
(ostream& operator<<(ostream& os, const Date& dd).
Was muss ich ändern, damit das Programm in main fehlerfrei ausgeführt
werden kann?
commanderKeen schrieb:>> Was muss ich ändern, damit das Programm in main fehlerfrei ausgeführt> werden kann?
einen operator << für das Enum Month anlegen, der dann z.B. den Monat in
Textform in den Stream schiebt.
Du hast es ja für Date auch hinbekommen ;-)
Oder Date gibt den Monat auch als String aus und operator << für Date
benutzt diese Methode statt month().
Carl D. schrieb:> Oder Date gibt den Monat auch als String aus und operator << für Date> benutzt diese Methode statt month().
Ich stehe gerade auf dem Schlauch, wie müsste ich den code abändern?
commanderKeen schrieb:>>> Fehler C2679: Binärer Operator "<<": Es konnte kein Operator gefunden werden,> der einen rechtsseitigen Operanden vom Typ "Month" akzeptiert (oder> keine geeignete Konvertierung möglich)
Weil sich enum class nicht implizit nach int konvertieren lässt. Das ist
einer der Unterschiede zum klassischen enum.
commanderKeen schrieb:> Ich möchte in der main-Funktion mit "cout" das Objekt "today" auf den> Bildschirm ausgeben, aber ich erhalte folgende Fehlermeldungen:
Wie soll es denn ausgegeben werden? Der Monat einfach als Zahl oder als
Name?
Egon N. schrieb:> Mir persönlich fehlen ja namespaces und die iostream. Die sind schon> drin? Bevor ich mir da den Code weiter anschau...
Möglicherweise in dem ominösen:
commanderKeen schrieb:> #include "../../std_lib_facilities.h"
Und das "dd.month" die richtigen Werte bekommt stellt ja mein
Konstruktor sicher. Ist das eine gute Lösung? Einfach ist sie ja, was
nicht immer gut sein muss.
commanderKeen schrieb:> Ist das eine gute Lösung?
Nein, C-Casts und dann auch noch in der "Funktion-Call" Syntax sind
unschön. Sicherer und besserer ist ein named cast:
Kassowarth von Sondermuehlen schrieb:> commanderKeen schrieb:>> : y{ yy }, m{ mm }, d{ dd }>> Was ist das für eine seltsame Initialisierung?> Was sagt der Compiler dazu eigentlich?
Das ist eine Memberinitialisiererliste, in den geschweiften Klammern
könnte auch Hunz und Kunz drin stehen, das sind die Werte mit denen man
ein Objekt initialisiert z.B. Date {1999, Month::mar, 12}; 1999 = yy,
Month::mar = mm usw.
Dr. Sommer schrieb:> static_cast<int>(dd.month())
Stimmt eine explizite Umwandlung ist besser, danke.
Dr. Sommer schrieb:> Wenn du es als Text haben willst, dann so wie Carl es schon gezeigt hat.
Ja das habe ich zur Kenntnis genommen, wollte aber nur Zahlenwerte,
hätte ich dazu schrieben sollen. Danke dir für den Vorschlag Carl.
commanderKeen schrieb:> as ist eine Memberinitialisiererliste
Ich glaube, die Frage bezog sich auf die geschweiften Klammern.
Ja, das ist neu zu C++11 dazugekommen, um an anderer Stelle die
Mehrdeutigkeiten aufzulösen, die durch runde Klammern entstehen, und es
nennt sich uniform initializer o.ä..
Dr. Sommer schrieb:> Nase schrieb:>> Ja, das ist neu zu C++11 dazugekommen,>> Das klärt aber immer noch nicht, wo die Ausdrücke dd, mm, yy definiert> sind...
Oder wo der Body des Konstruktors ist. Soweit ich weiß, darf auch in
neueren Versionen von C++ der Konstruktor nicht ausschließlich aus der
Initialisierungsliste bestehen.
Nein, named casts auch explizite Typumwandlung genannt, ist nur dann
erforderlich wenn man mittels Fehlerbehandlung eine verlustbehaftete
Umwandlung abfangen möchte.
guest schrieb:> Nein, named casts auch explizite Typumwandlung genannt, ist nur dann> erforderlich
Ich habe nicht gesagt dass sie erforderlich sind. Sie vermeiden aber
Fehler, weil sie dem Compiler strengere Prüfungen ermöglichen.
Tatsächlich können klassische C Casts alles was named casts können, und
sogar ein bisschen mehr - diese Fälle sind aber nur aus Abwärts
Kompatibilitäts Gründen erlaubt und sind grundsätzlich zu vermeiden.
Man sollte beides nutzen und wissen wann man es braucht:
Implizite Typumwandlung wenn man bewusst einen Wertverlust in kauf
nehmen kann/will
Explizite Typumwandlung wenn man einen Werteverlust vermeiden will und
darüber mittels Fehlerbehandlung informiert werden will.
guest schrieb:> Implizite Typumwandlung wenn man bewusst einen Wertverlust in kauf> nehmen kann/will>> Explizite Typumwandlung wenn man einen Werteverlust vermeiden will und> darüber mittels Fehlerbehandlung informiert werden will.
c-style und "named" casts sind beide explizit. In beiden Fällen muss man
explizit angeben, dass und wohin gecastet wird. In beiden Fällen kann es
zu Werteverlust kommen. Und was meinst du mit Fehlerbehandlung? Fehler
beim Compilieren, Exceptions oder was?
mh schrieb:> In beiden Fällen kann es> zu Werteverlust kommen
Du kannst das "static_cast..." Konstrukt in Verbindung mit Exception
handling nutzen um eine Meldung zu erhalten wenn ein Verlust beim
Konvertieren auftritt. Das geht mit C-Style casts nicht.
Der einzige Fall wo casten Exceptions wirft ist dynamic_cast mit
Referenzen... Aber dynamic_cast sollte man eh vermeiden und ist 95% der
Fälle ein Zeichen von schlechter Programmstruktur.
https://ideone.com/96Xfso
guest schrieb:> mh schrieb:>> In beiden Fällen kann es>> zu Werteverlust kommen>> Du kannst das "static_cast..." Konstrukt in Verbindung mit Exception> handling nutzen um eine Meldung zu erhalten wenn ein Verlust beim> Konvertieren auftritt. Das geht mit C-Style casts nicht.
Und wie geht das? static_cast selbst wirft keine Exception. Ok, wenn die
selbst implementierte Konvertierungsfunktion oder der Constructor eine
Exception wird ... aber das würde auch beim c-style Cast passieren.
Wenn man schon casten muss, dann bitte nur mit named casts.
Die kann man nämlich auch gut suchen im Sourcecode, was
bei C-casts schwierig ist.
Just my 2 cents
merciless
guest schrieb:> Man sollte beides nutzen und wissen wann man es braucht:>> Implizite Typumwandlung wenn man bewusst einen Wertverlust in kauf> nehmen kann/will>> Explizite Typumwandlung wenn man einen Werteverlust vermeiden will und> darüber mittels Fehlerbehandlung informiert werden will.
Ich würde sagen, genau umgekehrt. Compiler warnen, wenn durch eine
implizite Konvertierung ein Wertverlust eintreten könnte.
Mit einer expliziten Typumwandlungen sage ich dem Compiler dagegen, dass
ich das genau so will, auch wenn es einen Wertverlust bedeuten könnte ->
keine Compiler-Warnung mehr.