Frage

Betrachten Sie diesen Code,

struct A {};
struct B {  B(const A&) {} };
void f(B)
{
    cout << "f()"<<endl;
}
void g(A &a)
{
    cout << "g()" <<endl;
    f(a); //a is implicitly converted into B.
}
int main()
{
    A a;
    g(a);
}

Der compiles feine , läuft gut. Aber wenn ich Änderung f(B) zu f(B&), es nicht kompilieren . Wenn ich f(const B&) schreiben, wieder es feinen kompiliert, läuft gut. Warum ist der Grund und Begründung?

Zusammenfassung:

void f(B);         //okay
void f(B&);        //error
void f(const B&);  //okay

Ich mag Gründe hören, Begründung und Referenz (en) aus der Sprachspezifikation, für jeden dieser Fälle. Natürlich sind die Funktionssignaturen selbst nicht falsch. Vielmehr A implizit konvertiert in B und const B&, aber nicht in B&, und das bewirkt, dass der Übersetzungsfehler.

War es hilfreich?

Lösung

Ich mag Gründe hören, Begründung und Referenz (en) aus der Sprachspezifikation

Ist The Design und Entwicklung von C ++ ausreichend?

ich einen schweren Fehler gemacht, aber durch eine nicht konstante Referenz ermöglicht durch einen nicht-L-Wert initialisiert werden [ Kommentar von mir: Diese Formulierung ist ungenau !]. Zum Beispiel:

void incr(int& rr) { ++rr; }

void g()
{
    double ss = 1;
    incr(ss);    // note: double passed, int expected
                 // (fixed: error in release 2.0)
}

Aufgrund der Unterschiede in Art kann der int& nicht auf die double weitergegeben verweisen so eine temporäre generiert wurde ein int von ss Wert initialisiert zu halten. So modifizierte incr() die temporäre und das Ergebnis wurde nicht zurück an die anrufende Funktion [ Hervorhebung von mir ].

reflektiert

Denken Sie daran: Der ganze Sinn der Call-by-Referenz ist, dass der Client übergibt Dinge, die durch die Funktion geändert werden, und nachdem die Funktion zurückkehrt, muss der Kunde in der Lage sein, um die Änderungen zu beobachten .

Andere Tipps

Das Problem besteht darin, daß die implizite Umwandlung von einem Objekt zu einem B ergibt einen R-Wert. Nicht konstante Referenzen können nur an lvalues ??binden.

Wenn B einen Standardkonstruktor hat würden Sie das gleiche Verhalten, wenn Sie den f(a) Aufruf f(B()) ändern.

-

litb bietet eine große Antwort auf das, was ein L-Wert: Stack-Überlauf - häufig verwendet selten definierte Begriffe: L-Wert

GOTW # 88: ein Kandidat für den „wichtigsten const“

Stack-Überlauf - Wie kommen eine nicht konstante Referenz auf ein temporäres Objekt nicht binden?

-

Um mit Verweisen auf den Standard zu erklären, wie diese Funktionsaufrufe scheitern oder gelingen übermäßig lange wären. Das Wichtigste ist, wie B& b = a; ausfällt, während const B& b = a; nicht ausfällt.

(vom Entwurf n1905)

A reference „CV1 T1“ zu geben, indem ein Ausdruck des Typs initialisiert „CV2 T2“ wie folgt:
- [ ein L-Wert ist und entweder Referenz kompatibel oder implizit konvertierbar zu einem L-Wert einer Referenz kompatibelen Typs ... ]
-. Andernfalls ist die Bezugnahme auf einen nichtflüchtigen const Typ sein (das heißt, wird sein CV1 const)

Hier einen Fall, wo etwas zu einem L-Wert von Referenz kompatibelen Typ konvertierbar ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top