Betrachten Sie diesen Code,
%Vor% Dies kompiliert gut , läuft gut. Aber wenn ich f(B)
in f(B&)
ändere, kompiliert nicht . Wenn ich f(const B&)
schreibe, funktioniert es wieder gut , läuft gut. Warum ist der Grund und die Gründe?
Zusammenfassung:
%Vor% Ich möchte für jeden dieser Fälle Gründe, Begründungen und Referenzen aus der Sprachspezifikation hören. Natürlich sind die Funktionssignaturen selbst nicht falsch. Eher A
konvertiert implizit in B
und const B&
, aber nicht in B&
, und das verursacht den Kompilierungsfehler.
Ich würde gerne Gründe, Gründe und Referenzen von der Sprachspezifikation hören
Ist das Design und die Entwicklung von C ++ ausreichend?
Ich habe jedoch einen schwerwiegenden Fehler gemacht, indem ich zugelassen habe, dass eine nicht-konstante Referenz durch einen nicht-lvalue [ Kommentar von mir initialisiert wird: dieser Wortlaut ist ungenau! ]. Zum Beispiel:
%Vor%Wegen des Unterschieds in der Art kann
int&
nicht auf die übergebenedouble
verweisen, so dass eine temporäre generiert wurde, um eineint
vor dem Wertss
initialisiert zu halten. Daher hatincr()
das temporäre geändert und das Ergebnis wurde nicht in die aufrufende Funktion [ Hervorhebung von mir ] reflektiert.
Denken Sie darüber nach: Der Call-by-Reference-Punkt besteht darin, dass der Client Dinge übergibt, die von der Funktion geändert wurden, und nachdem die Funktion zurückgegeben wurde, muss der Client die Änderungen beobachten können >.
Das Problem ist, dass die implizite Umwandlung von einem in ein B-Objekt einen rvalue ergibt. Nicht-konstante Referenzen können nur an lvalues binden.
Wenn B einen Standardkonstruktor hätte, würden Sie dasselbe Verhalten erhalten, wenn Sie den f(a)
- Aufruf in f(B())
ändern.
-
litb bietet eine gute Antwort auf einen lvalue: Stack Overflow - oft verwendete selten definierte Begriffe: lvalue
GotW # 88: Ein Kandidat für die "Wichtigste const"
-
Mit Verweis auf den Standard zu erklären, wie diese Funktionsaufrufe fehlschlagen oder gelingen, wäre übermäßig lang. Wichtig ist, wie B& b = a;
fehlschlägt, während const B& b = a;
nicht fehlschlägt.
(aus Entwurf n1905)
Ein Verweis auf den Typ "cv1 T1" wird durch einen Ausdruck vom Typ "cv2 T2" wie folgt initialisiert:
- [ ist ein lvalue und ist entweder referenzkompatibel oder implizit in einen Lvalue eines referenzkompatiblen Typs konvertierbar ... ]
- Andernfalls muss der Verweis auf einen nichtflüchtigen const-Typ lauten (d. H. Cv1 muss const sein).
Hier ist ein Fall, in dem etwas in einen L-Wert mit einem Referenz-kompatiblen Typ umgewandelt werden kann.
Tags und Links c++ reference implicit-conversion const-reference