14

Beachten Sie Folgendes:Overloading Konvertierungsfunktion Vorlagen

struct X { 
    template <class T> operator T(); // #1 
    template <class T> operator T&(); // #2 
}; 

int  a = X{}; // error: ambiguous 
int&  b = X{}; // calls #2 
int const& c = X{}; // calls #2 

Die Situation für b einfach ist, #2 ist der einzig gangbare Kandidat. Was ist die Regel, die angibt, dass #2 ist #1 für die Initialisierung von int const& vorzuziehen, aber die beiden sind mehrdeutig für die Initialisierung von int?

+1

[\ [over.match.conv \]] (http://eel.is/c++draft/over.match.conv) und [\ [over.match.ref \]] (http://eel.is/c++draft/over.match.ref) scheint ein guter Ausgangspunkt zu sein. – jaggedSpire

+0

@jaggedSpire Diese Abschnitte zeigen an, was die Kandidatenfunktionen sind. Nicht wie man das eine oder das andere vorzieht (oder nicht). – Barry

+2

das Templating ist hier nicht essentiell, auch 'operator int' und' operator int & 'sind mehrdeutig – TemplateRex

Antwort

3

Bei der Entscheidung, wie eine Referenz initialisiert werden soll, wird zunächst eine direkte Bindung versucht. [dcl.init.ref]/(5.1.2):

Wenn die Referenz eine L-Wert Referenz und der Initialisierer Ausdruck ist [...] eine Klassentyp (dh T2 ist ein Klassentyp), wo T1 auf T2 nicht VERWEIS verwendet und sein kann Umgerechnet auf einen L-Wert vom Typ „CV3T3“, wobei „CV1T1“ reference-kompatibel mit „CV3T3“ (dieser Umwandlung durch Aufzählen der anwendbaren Umrechnungsfunktionen ausgewählt wird (13.3.1.6), und die Auswahl th Die beste Overload-Auflösung (13.3)), dann ist die Referenz an das Lvalue-Ergebnis der Konvertierung [...] gebunden. betrachtet werden

Die Umwandlungsfunktionen S und deren Basisklassen:

Die Formulierung, dass die Kandidatenauswahl für diesen Prozess (13.3.1.6, wie oben erwähnte) schließt die erste Umwandlungsfunktion regelt. Diese nicht-explizite Umwandlungsfunktionen , die nicht versteckt sind innerhalb S und Ausbeute Typ „lvalue Bezug auf CV2T2 (wenn ein L-Wert Kennnummer oder eine rvalue Bezug auf Funktion Initialisieren) [...], wobei „CV1T "Referenz-kompatibel (8.6.3) mit" cv2T2 ", sind Kandidatenfunktionen. Zur direkten Initialisierung, [...].

Offensichtlich ist dieser Ausschluss spezifisch für die Semantik der Referenzinitialisierung, so dass der erste Fall noch mehrdeutig ist.

+0

Aber Sie haben den Teil des Abschnitts weggelassen, der Konvertierungsfunktionen berücksichtigt, die * cv2 * 'T2' ergeben. Was ist mit dieser anderen Kandidatenfunktion passiert? – Barry

+0

@Barry gilt nicht nur für die "Initialisierung einer R-Wert-Referenz oder eines L-Wert-Verweises auf Funktion", oder fehlt mir Ihre Bedeutung? – jaggedSpire

+0

@jaggedSpire Ich wollte sagen, Barry verwirrte mich für eine Sekunde. Wenn eine Konvertierungsfunktion einen Pr-Wert zurückgibt, wie kann eine lvalue-Referenz direkt an sie gebunden werden? Das würde den Punkt dieses Abschnitts etwas verfehlen. – Columbo