Implizite Konvertierung: const Referenz vs. nicht konstante Referenz vs. Nicht-Referenz

8

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.

    
Nawaz 16.01.2011, 08:09
quelle

2 Antworten

7
  

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 übergebene double verweisen, so dass eine temporäre generiert wurde, um eine int vor dem Wert ss initialisiert zu halten. Daher hat incr() 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 >.

    
fredoverflow 16.01.2011, 09:20
quelle
4

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"

Stack Overflow - Wie kommt es? Eine nicht konstante Referenz kann nicht an ein temporäres Objekt gebunden werden?

-

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.

    
Chris Hopman 16.01.2011 08:32
quelle