Fehler: Aufruf des überladenen »Meter(Feet&)« ist mehrdeutig
-
Hallo zusammen,
ich hab folgendes Problem und hoffe ihr könnt mir helfen.
Mein gcc Compiler sagt mir beim kompilieren, dass der Aufruf für den Cast nicht eindeutig sei.
Fehler: Aufruf des überladenen »Meter(Feet&)« ist mehrdeutig
Anmerkung: Kandidaten sind: Meter::Meter(const Meter&)
Anmerkung: Meter::Meter(double)Ich habe folgende Klassen erstellt:
class Meter : public Oberklasse { private: double value; public: operator double const () {return value}; operator Feet const () {return static_cast<Feet>(this->value * 1/3.0); set (Meter newvalue) { value = newvalue.get()}; set (Feet newvalue) {this.set((Meter)newvalue); /* Hier ist dann der Compiler fehler */ }
class Feet : public Oberklasse { private: double value; public: operator double const (){return value}; operator Meter const () {return static_cast<Meter>(this->value * 3.0); }
Der Aufruf sieht wie folgt aus:
Meter strecke (0.0); Feet strecke2 (3.0); strecke.set(strecke2);
Die "operator double const ()" Funktion ist nur für die Bequemlichkeit vorhanden, um den Value ohne ein get aus der Klasse zu verwenden. Wenn ich diese Funktion auskommentiere, funktioniert der Cast einwandfrei.
Hoffe ihr versteht mein Problem und könnt mir helfen.
-
Feet kann mittels seiner Casting-Operatoren automatisch sowohl double als auch Meter sein. Der Meter-Kopierkonstruktor wird automatisch erstellt, falls man ihn nicht selbst definiert. Welcher der beiden passenden Meter-Konstruktoren soll genommen werden? Soll Feet automatisch double werden und nach Meter gecastet werden, oder soll Feet automatisch Meter werden, um zugewiesen zu werden? Das musst Du an der von Dir vermerkten Stelle explizit sagen.
set(newvalue.operator Meter()); // Hier ist dann kein Compiler-Fehler mehr
-
Vielen Dank, funktioniert wunderbar.
An nen direkten Aufruf hatte ich gar net gedacht.
-
Dieses Durcheinander ist einer der Gründe, warum ich Konvertierungsoperatroren vermeiden und die Konstruktoren mit Argument explict machen würde. Für Konvertierungen kann man dann ja extra Funktionen (toDouble() oder so) schreiben.
-
Mehrere Konvertierungsoperatoren sind oft gefährlich, besonders wenn die Typen wie hier noch untereinander kompatibel sind.
Brauchst du denn
Meter
oderFeet
so oft in einemdouble
-Kontext? Ich würde so oder so Memberfunktionen anbieten. Denn dass man den Konvertierungsoperator explizit aufrufen muss, verfehlt den Sinn der Sache.
-
Irgendwie habe ich genau das auch gemeint.
-
Nexus schrieb:
Denn dass man den Konvertierungsoperator explizit aufrufen muss, verfehlt den Sinn der Sache.
Finde ich nicht - gerade in diesem Zusammenhang nicht... Weil er wohl kaum die exakte Umrechnungszahl haben wird und mit ihr rechnet - und wenn er dann paar mal (unbeabsichtigerweise) umrechnet und zwischendrin noch Rechenoperation x ausführt, dann hat er irgendwann nen problem mit der Genauigkeit...
Ansonsten bin ich eigtl auch kein Fan von explicit - aber in dem Kontext find ich es (imho ^^) durchaus vertretbar...bb
-
unskilled schrieb:
Finde ich nicht - gerade in diesem Zusammenhang nicht... Weil er wohl kaum die exakte Umrechnungszahl haben wird und mit ihr rechnet - und wenn er dann paar mal (unbeabsichtigerweise) umrechnet und zwischendrin noch Rechenoperation x ausführt, dann hat er irgendwann nen problem mit der Genauigkeit...
Ansonsten bin ich eigtl auch kein Fan von explicit - aber in dem Kontext find ich es (imho ^^) durchaus vertretbar...Mir scheint, du hast nicht genau gelesen oder falsch verstanden.
Ich plädierte schliesslich dafür, von den Cast-Operatoren wegzukommen. Also in Richtung
explicit
beim Konstruktor und Konvertierungs-Memberfunktionen. Oder wie meinst du das?
-
Nexus schrieb:
Mir scheint, du hast nicht genau gelesen
sry ^^
-
Ich bin nur der Lakai, der das so programmieren soll.
Gefordert wirds vom Chef und so wie im Problem oben beschrieben muss nur an dieser Stelle dort gecastet werden.
-
unskilled schrieb:
Nexus schrieb:
Denn dass man den Konvertierungsoperator explizit aufrufen muss, verfehlt den Sinn der Sache.
Finde ich nicht - gerade in diesem Zusammenhang nicht... Weil er wohl kaum die exakte Umrechnungszahl haben wird und mit ihr rechnet - und wenn er dann paar mal (unbeabsichtigerweise) umrechnet und zwischendrin noch Rechenoperation x ausführt, dann hat er irgendwann nen problem mit der Genauigkeit...
Gerade aus dem Grund ist der Konvertierungsoperator hier fehl am Platze. Konvertierungsoperatoren sind einzig dazu da, implizite Konvertierungen zu ermöglichen. Und implizite Konvertierungen sind nur dann sinnvoll, wenn der Entwickler der sie benutzt sich keinen Kopf um irgendwelche Nebenwirkungen wie z.B. Genauigkeitsverluste etc. machen muss. In dem Fall ist der Konvertierungsoperator also doppelt fehl am Platz: zum einen weil er statt implizite Konvertierungen zu ermöglichen nur die Fehlermeldung des Compilers komplizierter macht (vorher "keine Konvertierung vorhanden", jetzt "Konvertierung mehrdeutig"), zum anderen weil er den Genauigkeitsverlust verschleiert. Daher ist die toDouble-Methode oder ein expliziter Konstruktor vorzuziehen.
Arkon schrieb:
Ich bin nur der Lakai, der das so programmieren soll.
Gefordert wirds vom Chef und so wie im Problem oben beschrieben muss nur an dieser Stelle dort gecastet werden.Wenn du ein einfacher Lakai und Tastaturknecht bleiben willst (und damit Gefahr laufen möchtest dass deine Arbeit irgendwann nach Indien ausgelagert wird) dann bleib dabei. Wenn nicht, dann zeig deinem Chef dass du Köpfchen hast und mitdenkst und erklär ihm dass das was er gefordert hat zu Problemen führen kann und evtl. nicht ganz durchdacht ist