2017-04-10 12 views
-3

Ich habe eine Klasse namens uniVal mit definierter Konvertierung in int_64 double und string. Wenn ich versuche, Objekt dieser Klasse zu vergleichen GCC sagt int: Kandidaten sind:C++ - Operator == und benutzerdefinierte Typumwandlungen

operator==(int, int) <built-in> 
operator==(int64_t {aka long int}, int) <built-in> 
operator==(unsigned int, int) <built-in> 
operator==(long unsigned int, int) <built-in> 
operator==(float, int) <built-in> 
operator==(double, int) <built-in> 
error: ambiguous overload for ‘operator==’ (operand types are ‘uniVal’ and ‘int’) 

aber wenn ich doppelt zu werfen angeben werden explizit kompiliert. Ist es möglich, dass gcc den Konvertierungstyp wählt, der dem anderen Argumenttyp am nächsten kommt?

UPD: Schreiben eigenen Operators == für jede Typkombination wird, natürlich, dies zu lösen, aber ich möchte diese Klasse mit allen C++ - Typen arbeiten, also möchte ich nur eine Reihe von Konvertierungsfunktionen schreiben und machen Complier mache den Rest.

+0

Wenn Sie Ihren eigenen 'operator == (uniVal, int)' und 'operator == (int, uniVal)' geschrieben haben, sollte das Problem lösen – Justin

Antwort

0

Ist es möglich, dass gcc den Konvertierungstyp wählt, der anderen Argumenten am nächsten kommt?

Kurze Version: Nein, weil bei der Überladungsauflösung die Beziehung der einzelnen Parametertypen nicht berücksichtigt wird.

Lange Version:

Der Compiler findet alle lebensfähigen Funktionen (dh alle Funktionen, die theoretiaclly kann mit den gegebenen Parametern über Umwandlung oder direkt aufgerufen werden) und ordnet sie gegeneinander an. Die Überladungsauflösung ist nur dann erfolgreich, wenn genau eine der realisierbaren Funktionen strikt besser ist als alle anderen. Eine genaue Auflistung, wie Funktionen miteinander verglichen werden, ist verfügbar here (Abschnitt "Bestmögliche Funktion"). Für diesen speziellen Fall ist nur Folgendes relevant:

F1 ist eine bessere Funktion als F2, wenn die impliziten Konvertierungen für alle Argumente von F1 nicht schlechter sind als die impliziten Konvertierungen für alle Argumente von F2, und [ ...] gibt es mindestens ein Argument von F1, dessen implizite Konvertierung besser ist als die entsprechende implizite Konvertierung für dieses Argument von F2 [...]

Die übrigen Regeln sind in Ihrem Kontext nicht anwendbar, da die Rückkehr Typ für jeden der Operatoren ist der gleiche und sie sind keine Vorlagen (oder Spezialisierungen davon). Ihr zweiter Operand erfordert auch keine Konvertierung (in der Untergruppe der in Ihrer Frage vorhandenen Überladungen). Es geht also um die Konvertierung von uniVal zu long und double und die folgenden numerischen Werbeaktionen/Conversions.

Die Umwandlung Sequenzen sind jeweils entsprechend der folgenden (siehe here; Abschnitt "Ranking der impliziten Umwandlungs sequences") rangiert:

  1. Exact Match: keine Konvertierung erforderlich, L-Wert-zu-rvalue Umwandlung, Qualifizierungs-Umwandlung, benutzerdefinierte Umwandlung von Klassentyp zur selber Klasse

  2. Promotion: integrale Förderung, Gleitkommazahlen Förderung

  3. Umwandlung: integrale Umwandlung, Gleitkommazahlen Umwandlung Floating-Integral-Konvertierung, Zeigerumwandlungs, pointer-to-Mitglied Umwandlung, boolean Umwandlung, benutzerdefinierte Umwandlung einer abgeleiteten Klasse mit seiner Basis

In Ihrem Fall erfordern sowohl long int als auch double keine zusätzlichen Konvertierungen zusätzlich zu Ihrer benutzerdefinierten Konvertierung. Somit sind sie gleichrangig zueinander (sind aber besser als die anderen Kandidaten, die benötigen würden zusätzliche Konvertierungen erfordern). Daher ist Ihr Anruf mehrdeutig.

Sie werden feststellen, dass es keinen Punkt gibt, an dem die verschiedenen Parametertypen verglichen werden. Dies ist (nicht?) Aus einem guten Grund getan: Schließlich dürfen die Parameter im Funktionskörper überhaupt nicht miteinander verwendet werden (realistisch gesehen werden sie in operator== sein, aber für den Compiler ist das nur eine Funktion) wie alle anderen), in welchem ​​Fall der Vergleich ihrer Typen keinerlei nützliche Informationen liefern würde.

+0

Ich weiß, dass dies den Bereich der Frage etwas verlassen. Ich verpasste ein kleines Detail über das, was gefragt wurde, bis ich es größtenteils fertigbrachte, so dass ich dachte, ich würde einfach beenden, was ich angefangen habe. – Pandatyr

+0

Nun, ich fand diese Informationen sehr nützlich, also danke – Gammamad

Verwandte Themen