2017-02-19 1 views
0

Kompilieren der folgende:Achtung: Hinweis auf lokale temporäre Objekt zurückkehr

namespace platform { 
    struct event {}; 
    struct keyboard_event : public event {}; 

    const platform::event& wait_event() 
    { 
    return platform::keyboard_event(); 
    } 
} 

int main(int argc, const char* argv[]) 
{ 
    const platform::event& event = platform::wait_event(); 
    return 0; 
} 

ergibt die folgende Warnung mit Klirren

main.cc:7:12: warning: returning reference to local temporary object [-Wreturn-stack-address] 
    return platform::keyboard_event(); 
      ^~~~~~~~~~~~~~~~~~~~~~~~~~ 

jedoch eine konstante Referenz auf etwas Rückkehr verlängert seine Lebensdauer es nicht ?

Der aktuelle Entwurf nicht für mich wird geladen, so werde ich zitieren cppreference.com statt:

Die Lebensdauer eines temporären Objekts kann durch Bindung an eine const lvalue Referenz oder auf einen R-Wert Bezug verlängert werden (seit C++ 11), siehe Referenzinitialisierung für Details.

Wie kann ich das umschreiben, um den gleichen Effekt zu haben, aber die Warnung vermeiden?

+0

'platform :: keyboard_event()' ist r-Wert. Sie binden es mit 'const &' und geben es zurück. Aber Sie können keinen Verweis auf temp, const oder nicht zurückgeben. Es ist eine klassische Warnung "Rückkehr zur temporären Warnung". – xinaiz

+0

Wenn Sie dem Link in "Siehe Referenzinitialisierung für Details" folgen, fährt cppreference fort, zu sagen "eine temporäre Bindung an einen Rückgabewert einer Funktion in einer return-Anweisung ist nicht erweitert" – Cubbi

Antwort

2

Nein, "eine Referenz zurückzugeben" verlängert die Lebensdauer nicht magisch.

Das einzige Mal, dass Lebensdauer verlängert wird, wenn ein prvalue auf eine Referenz Variable, und die Lebensdauer des prvalue verlängert wird, dass die Variablen gebunden ist:

struct Foo{}; 

{ 
    const auto & r = Foo{}; // Foo object not destroyed at semicolon... 
    // ... 
} 
// ... but is destroyed only here. 

Ihre prvalue nicht gebunden ist zu irgendeiner Variable, und daher wird keine Lebenszeit verlängert.

(Beachten Sie auch, dass nicht-statische Klassendatenelemente gelten nicht als „Variablen“ für diese Überlegung, so können Sie auch nicht über Lebensdauer Konstruktor initializer Listen erweitern, wenn Ihre Klasse Referenzelemente haben passiert.)

+0

Okay, so dass es bis zu undefiniert Verhalten funktioniert/Glück, dass sich der Stack nicht verändert hat. Eine Verlängerung der Lebensdauer um Const-Wert- oder R-Wert-Referenzen kann daher in keinem Szenario als Referenz verwendet werden. –

+0

@CasperBeyer nein, nur Rückgabe nach Wert - was wäre in diesem Fall in Ordnung –

+0

Rückgabe von Wert würde in diesem Fall verursachen Slicing, nein? (vorausgesetzt, es gibt verschiedene Datensätze pro Struktur) –

Verwandte Themen