Heim >Backend-Entwicklung >C++ >Können C 11 Lambdas Referenzen erfassen, ohne undefiniertes Verhalten hervorzurufen?
Referenzen in C 11 Lambdas erfassen
In C können Lambda-Ausdrücke Variablen aus ihrem umschließenden Bereich erfassen. Die Erfassungsmethode bestimmt jedoch, ob auf die Variable per Referenz oder per Wert zugegriffen wird. Betrachten Sie den folgenden Code:
<code class="cpp">#include <functional> #include <iostream> std::function<void()> make_function(int& x) { return [&]{ std::cout << x << std::endl; }; } int main() { int i = 3; auto f = make_function(i); i = 5; f(); }</code>
Dieser Code erfasst die Variable x durch Referenz mithilfe der [&]-Syntax. Es stellt sich die Frage, ob dieses Programm die Ausgabe von 5 garantiert, ohne undefiniertes Verhalten hervorzurufen.
Antwort: Ja
Der Code funktioniert garantiert korrekt. Vor der Prüfung des zugrunde liegenden Standardwortlauts ist es wichtig zu beachten, dass dieser Kodex wie vom C-Komitee beabsichtigt funktioniert. Allerdings war der ursprüngliche Wortlaut des C 11-Standards in dieser Angelegenheit unklar, was dazu führte, dass CWG-Problem 2011 zur Klärung herangezogen wurde. Dieses Problem wird in der laufenden Entwicklung des C-Standards behoben.
Standarderklärung
Gemäß [expr.prim.lambda]/17 des C-Standards, Nur ID-Ausdrücke, die sich auf durch Kopieren erfasste Entitäten beziehen, werden in einen Mitgliedszugriff auf den Lambda-Schließungstyp umgewandelt. ID-Ausdrücke, die sich auf per Referenz erfasste Entitäten beziehen, werden in Ruhe gelassen und bezeichnen weiterhin dieselbe Entität, die sie im umschließenden Bereich bezeichnet hätten.
Im obigen Code ist die erfasste Entität der Parameter x der Funktion make_function , was in den Reichweitenbereich des Lambda fällt. Daher bezieht sich die Referenz x im Lambda-Ausdruck auf die ursprüngliche Variable, die in der Hauptfunktion deklariert wurde.
Es kann zunächst problematisch erscheinen, dass x außerhalb seiner Lebensdauer referenziert wird, nachdem die Funktion make_function zurückkehrt. Es gibt jedoch begrenzte Szenarien, in denen auf eine Referenz außerhalb ihrer Lebensdauer verwiesen werden kann. Im Allgemeinen wird eine Referenz entweder im Gültigkeitsbereich deklariert oder ist ein Klassenmitglied. In diesem Fall muss die Klasse selbst innerhalb ihrer Lebensdauer liegen.
Daher verbietet der Standard nicht ausdrücklich die Verwendung von Referenzen außerhalb ihrer Lebensdauer. Diese Lücke ermöglichte die Unterstützung der Erfassung von Referenzen durch Referenz in Lambda-Ausdrücken.
CWG-Ausgabe 2012 und zukünftige Klarstellung
CWG-Ausgabe 2012 wurde angesprochen, um das Versehen zu beheben dass Referenzen unter Umständen außerhalb ihrer Lebensdauer referenziert werden könnten. Die Lösung dieses Problems hatte unbeabsichtigt Auswirkungen auf die Spezifikation für die Lambda-Erfassung durch Verweis auf Referenzen. Es wird jedoch erwartet, dass diese Regression vor der Veröffentlichung von C 17 behoben wird.
Das obige ist der detaillierte Inhalt vonKönnen C 11 Lambdas Referenzen erfassen, ohne undefiniertes Verhalten hervorzurufen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!