3

Wenn ich ein struct A wie folgt definiert:C++ Operator == und implizite Konvertierung Auflösung

struct A { 
    const char *data; 
    operator const char *() const { return data; } 
    friend bool operator== (const A &s1, const char *s2) 
    { return /* typical string comparison result */; } 
}; 

Und ich schreibe A{"hello"} == "test2" wird A::operator== genannt? Was im Standard besagt, dass (und warum ist nicht die A implizit in const char * konvertiert?)

Was ist mit "test2" == A{"hello"}? Ist in diesem Fall die A konvertiert?

EDIT: Was ist, wenn struct A hat auch Mitglied:

friend bool operator== (const char *s1, const A &s2) 
+0

verwenden Sie einfach std :: string – Davidbrcz

+0

@Davidbrcz Das ist nicht, was diese Frage überhaupt ist. –

+0

Ich dachte 'Freund' macht die Funktion ** non ** - Mitglied (d. H. Global). –

Antwort

4

Wenn Sie das tun

A{"hello"} == "test2" 

wir Überlastung Auflösung auf operator== zuführen. Erstens finden wir die geeigneten Kandidaten ([over.match.viable]), über Namen-Suche:

operator==(A const&, const char*); // yours 
operator==(const char*, const char*); // built-in 

Als nächstes bestimmen wir, welche Kandidaten die beste implizite Konvertierung Sequenz hat. Dies ist das erste Tie-Break in [over.match.best]:

diese Definitionen gegeben, eine tragfähige Funktion F1 ist definiert als eine besser Funktion als eine andere tragfähige Funktion F2 wenn für alle Argumente i zu sein, ICS i (F1) nicht eine schlechtere Konvertierungssequenz als ICS i (F2) und dann
(1.3) - aus irgendeinem Argumente j, ICS j (F1) ist eine bessere Umwandlungsfolge als ICS j (F2), oder, falls nicht, [...]

Beide Betreiber sind Exact Match im 2. Argument. Beim ersten Argument ist Ihre operator== eine exakte Übereinstimmung, während die integrierte Konvertierung eine benutzerdefinierte Konvertierung erfordert. Exakte Übereinstimmung ist die beste Art der Konvertierung und benutzerdefiniert ist die schlechteste - daher hat Ihre die bessere Konvertierungssequenz und wird die beste praktikable Funktion.

Im weiteren Sinne wird die A nicht implizit in eine const char* umgewandelt, weil es eine bessere Option gibt, wo es nicht sein muss.


Wenn Sie das tun:

"test2" == A{"hello"}; 

Ihr Kandidat nicht lebensfähig ist - es gibt keine implizite Konvertierung const char*-A const& ist (erstes Argument), so dass der einzige brauchbare Kandidat ist die eingebaute im Vergleich für const char*, die die benutzerdefinierte Umwandlung von A zu const char* erfordert. Wenn Sie möchten, dass A::operator== aufgerufen wird, müssen Sie eine neue Überladung für operator==(const char*, A const&) hinzufügen.

+0

Ich denke OP war nach dem relevanten Teil im Standard, der entschieden hat, was und warum es hier passiert. –

+0

Nur um klar zu sein: Im zweiten Fall, wenn ich 'A :: A (const char * s) {}' hätte, dann würde effektiv 'A (" test ") == A {" hallo "}' heißen? oder muss es eine implizite Konvertierung sein? – Olivetree

+0

@GillBates Ja, ich war, also konnte ich all die anderen Fälle kennen, an die ich gerade nicht gedacht habe. Ich denke, sie würden in den gleichen Regeln. Vielleicht sollte ich die Frage klären? – Olivetree