Der Standard scheint zwei Regeln zur Unterscheidung zwischen impliziten Konvertierungssequenzen, die benutzerdefinierte Konvertierungsoperatoren beinhalten, vorzusehen:
13.3.3 Beste brauchbare Funktion [over.match.best]
[...] eine lebensfähige Funktion F1 wird als bessere Funktion bezeichnet als F2, wenn [...]
- der Kontext ist eine Initialisierung durch benutzerdefinierte Konvertierung (siehe 8.5, 13.3.1.5 und 13.3.1.6) und die Standardkonvertierungssequenz vom Rückgabetyp von F1 zum Zieltyp (d.h. dem Typ der Entität, die initialisiert wird) eine bessere Konvertierungssequenz ist als die Standardkonvertierungssequenz vom dem Rückgabetyp von F2 in den Zieltyp.
13.3.3.2 Rangfolge impliziter Konvertierungssequenzen [over.ics.rank]
3 - Zwei implizite Konvertierungssequenzen der gleichen Form sind ununterscheidbare Konvertierungssequenzen der folgenden Regeln gilt: [...]
- Die benutzerdefinierte Konvertierungssequenz U1 ist eine bessere Konvertierungssequenz als eine andere benutzerdefinierte Konvertierungssequenz U2, wenn sie die gleiche benutzerdefinierte Konvertierungsfunktion oder den gleichen Konstruktor oder das gleiche Aggregat enthält Initialisierung enthalten und die zweite Standardkonvertierungsfolge von U1 besser ist als die zweite Standard Konvertierungssequenz von U2.
So wie ich es verstehe, erlaubt 13.3.3 dem Compiler zu unterscheiden zwischen verschiedene benutzerdefinierte Umwandlungsoperatoren , während 13.3.3.2 dem Compiler erlaubt, zu unterscheiden zwischen verschiedene Funktionen (Überladungen einer Funktion f
), die jeweils eine benutzerdefinierte Konvertierung in ihren Argumenten erfordern (siehe meine Seitenleiste zu Warum wird bei folgendem Code (in GCC 4.3) die Umwandlung in eine Referenz zweimal aufgerufen? ).
Gibt es noch andere Regeln, die zwischen benutzerdefinierten Konvertierungssequenzen unterscheiden können? Die Antwort unter https://stackoverflow.com/a/1384044/567292 weist darauf hin, dass 13.3.3.2:3 zwischen benutzerdefinierten Konvertierungssequenzen auf der Grundlage der cv-Qualifikation des impliziten Objektparameters (für einen Konvertierungsoperator) oder des einzelnen Nicht-Standardparameters für einen Konstruktor oder eine Aggregatinitialisierung unterscheiden kann, aber ich sehe nicht, wie das relevant sein kann, da dies einen Vergleich zwischen den ersten Standardkonvertierungssequenzen der jeweiligen benutzerdefinierten Konvertierungssequenzen erfordern würde, was der Standard nicht zu erwähnen scheint.
Angenommen, S1 ist besser als S2, wobei S1 die erste Standardkonvertierungssequenz von U1 und S2 die erste Standardkonvertierungssequenz von U2 ist, folgt daraus, dass U1 besser ist als U2? Mit anderen Worten: Ist dieser Code wohlgeformt?
struct A {
operator int();
operator char() const;
} a;
void foo(double);
int main() {
foo(a);
}
g++ (4.5.1), Clang (3,0) und Comeau (4.3.10.1) akzeptieren es und bevorzugen die nicht-konst-qualifizierte A::operator int()
aber ich würde erwarten, dass er als zweideutig und damit als unvollständig abgelehnt wird. Ist dies ein Mangel in der Norm oder in meinem Verständnis der Norm?