Ist das folgende (erfundenes Beispiel) in Ordnung oder ist es undefiniertes Verhalten:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
quelle
Ist das folgende (erfundenes Beispiel) in Ordnung oder ist es undefiniertes Verhalten:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
Es ist sicher. Const ref verlängert die Lebensdauer von temporären. Der Geltungsbereich ist der Geltungsbereich von const ref.
Die Lebensdauer eines temporären Objekt kann durch Bindung an eine const lvalue Referenz oder auf eine R - Wert - Referenz (da C ++ 11) verlängert werden, siehe Bezug Initialisierung für weitere Einzelheiten.
Immer wenn eine Referenz an ein temporäres Objekt oder an ein Unterobjekt davon gebunden ist, wird die Lebensdauer des temporären Objekts mit den folgenden Ausnahmen verlängert, um der Lebensdauer der Referenz zu entsprechen :
- Eine temporäre Bindung an einen Rückgabewert einer Funktion in einer return-Anweisung wird nicht erweitert: Sie wird sofort am Ende des return-Ausdrucks zerstört. Eine solche Funktion gibt immer eine baumelnde Referenz zurück.
- Eine temporäre Bindung an ein Referenzelement in einer Konstruktorinitialisiererliste bleibt nur so lange bestehen, bis der Konstruktor beendet wird, nicht solange das Objekt vorhanden ist. (Hinweis: Eine solche Initialisierung ist ab DR 1696 schlecht ausgebildet.)
- Eine temporäre Bindung an einen Referenzparameter in einem Funktionsaufruf besteht bis zum Ende des vollständigen Ausdrucks, der diesen Funktionsaufruf enthält: Wenn die Funktion eine Referenz zurückgibt, die den vollständigen Ausdruck überlebt, wird sie zu einer baumelnden Referenz.
- Eine temporäre Bindung an eine Referenz im Initialisierer, die in einem neuen Ausdruck verwendet wird, ist bis zum Ende des vollständigen Ausdrucks vorhanden, der diesen neuen Ausdruck enthält, nicht solange das initialisierte Objekt. Wenn das initialisierte Objekt den vollständigen Ausdruck überlebt, wird sein Referenzelement zu einer baumelnden Referenz.
- Bis zum Ende des vollständigen Ausdrucks, der den Initialisierer enthält, ist eine temporäre Bindung an eine Referenz in einem Referenzelement eines Aggregats vorhanden, das mit der Direktinitialisierungssyntax (Klammern) im Gegensatz zur Listeninitialisierungssyntax (geschweifte Klammern) initialisiert wurde.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
Im Allgemeinen kann die Lebensdauer eines Temporärs nicht durch "Weitergabe" weiter verlängert werden: Eine zweite Referenz, die aus dem Verweis initialisiert wurde, an den das Temporär gebunden war, hat keinen Einfluss auf seine Lebensdauer.
wie @Konrad Rudolph betonte (und siehe den letzten Absatz von oben):
"Wenn
c.GetSomeVariable()
eine Referenz auf ein lokales Objekt oder eine Referenz zurückgegeben wird, die selbst die Lebensdauer eines Objekts verlängert, wird die Lebensdauerverlängerung nicht aktiviert."
c.GetSomeVariable()
eine Referenz auf ein lokales Objekt oder eine Referenz zurückgegeben wird, die selbst die Lebensdauer eines Objekts verlängert, wird die Lebensdauerverlängerung nichtDank der Verlängerung der Lebensdauer sollte hier kein Problem auftreten . Das neu erstellte Objekt bleibt bestehen, bis die Referenz den Gültigkeitsbereich verlässt.
quelle
Ja, das ist absolut sicher: Die Bindung an eine
const
Referenz verlängert die Lebensdauer der temporären Referenz auf den Umfang dieser Referenz.Beachten Sie, dass das Verhalten jedoch nicht transitiv ist . Zum Beispiel mit
cc
baumelt.quelle
Das ist sicher.
quelle
In diesem speziellen Fall ist es sicher. Beachten Sie jedoch, dass nicht alle Provisorien sicher durch konstante Referenz erfasst werden können ... zum Beispiel
Die für erhaltene Referenz
z
ist NICHT sicher zu verwenden, da die temporäre Instanz am Ende des vollständigen Ausdrucks zerstört wird, bevor dieprintf
Anweisung erreicht wird. Ausgabe ist:quelle