2016-02-12 11 views
6

Ich frage mich, warum die Rückgabe const reference eines lokalen Objekts ist illegal, während die Rückgabe einer local object ist legal, solange Sie es an eine const reference zuweisen?Rückgabe const Referenz vs temporäres Objekt

vector<int> f_legal() { 
    vector<int> tempVec; 
    tempVec.push_back(1); 
    return tempVec; 
} 

const vector<int>& f_illegal() { 
    vector<int> tempVec; 
    tempVec.push_back(1); 
    return tempVec; 
} 

void g() { 
    const vector<int>& v1 = f_legal(); // legal 
    const vector<int>& v2 = f_illegal(); // illegal 
} 

Edit: Mein Punkt ist, dass, wenn ein const ref zu einer zurück lokalen Variablen zugewiesen legal ist, dann sollte kein const ref auf einen zurück const ref einer lokalen Variablen zuweisen als auch legal sein?

+2

@Ed Heal Ja, es ist in C++ klar definiert, dass eine lokale const-Referenz die Lebensdauer eines temporären Objekts, an das es gebunden ist, verlängert. –

+2

@EdHeal Ja, es ist legal. Es gibt einen speziellen Fall im Standard, der ein lokales Objekt am Leben erhält, solange es im aktuellen Bereich eine konstante Referenz darauf gibt. –

Antwort

6

Auch wenn Sie es auf eine konstante Referenz zuweisen, der Rückgabewert deklariert wird als Wert übergeben, bedeutet, dass es [1] nach außen als ein temporären Objekt kopiert werden, und dann auf die konstante Referenz binded . Die Bindung eines temporären Objekts an eine const Referenz ist in Ordnung, das Objekt wird nicht zerstört, bis die Lebensdauer der const-Referenz überschritten ist.

Auf der anderen Seite ist die Rückkehr Referenz einer lokalen Variablen Illegel. Die lokale Variable wird zerstört, wenn die Funktion zurückgegeben wird, dh die externe Referenz wird unterbrochen.

EDIT

Mein Punkt ist, dass, wenn ein const ref zu einer zurück lokalen Variablen zugewiesen legal ist, dann sollte eine const ref auf einen zurück const ref einer lokalen Variablen nicht zuweisen legal sein als Gut?

Der Punkt ist der erste Fall ist kein const ref zu einem zurück lokalen Variablen zugewiesen, es ist ein const ref auf eine temporäre Variable zurück zuweisen. (Was kann aus der lokalen Variablen kopiert.)


[1] Die Kopie kann technisch nach RVO weggelassen werden.

+0

Sind Sie sicher, dass das immer der Fall ist? Selbst wenn man 'RVO/NRVO' betrachtet? –

+0

@JamesAdkison: Es wird ein temporäres Objekt geben, und die Referenz wird an dieses temporäre Objekt gebunden. Die Kopie kann entfernt werden (wenn das Ergebnis direkt im temporären erstellt werden kann). –

+0

@BenVoigt Ja, das war mein Punkt (d. H. Die Kopie könnte weggelassen werden). –

8

Die Rückgabe eines Verweises auf eine lokale Variable ist unzulässig (Undefined Behavior). Zeitraum. Es gibt keine const oder mutable Klausel.

Dies liegt daran, dass lokale Funktionsvariablen eine automatische Speicherdauer haben. Sie werden "zerstört", nachdem die Funktion beendet wurde. Wenn die Funktion einen Verweis auf eine solche Variable zurückgibt, wird sie als unbestimmt bezeichnet: Sie verweist auf ein Objekt, das nicht mehr existiert.

Die erste ist legal wegen einer speziellen C++ - Regel: Initialisieren einer Referenz auf eine prvalue verlängert die Lebensdauer dieses temporären Objekts auf die Lebensdauer der Referenz.

+0

Die Regel hat eigentlich nichts mit 'const' zu tun - jede Referenz, die * direkt * an ein temporäres Objekt gebunden ist, verlängert die Lebensdauer dieses temporären Objekts.In C++ 98 sahen andere Regeln vor, dass nur Const-Referenzen direkt an ein Temporäres binden konnten. Diese Regeln haben sich nun geändert, was einen Domino-Effekt auf die Lebensdauerverlängerungsregel hatte. –

+0

@BenVoigt Das ist das erste Mal, dass ich davon höre. Könnten Sie eine Referenz angeben? – bolov

+0

Siehe http://stackoverflow.com/a/3716360/103167 –

1

Wahrscheinlich, weil es die Stack-basierten Aufrufkonventionen ruinieren würde, die uns seit Jahrzehnten gut gedient haben ..., die so ziemlich jede CPU annimmt.