2016-04-22 2 views
4

Mit C++ Lambda, was passiert, wenn Sie eine Referenz als Referenz erfassen? Erfassen Sie einen Verweis auf ein lokales Objekt im Stapel (die Referenz selbst) oder einen Verweis auf das Objekt, auf das verwiesen wird? Eg in den folgenden Code:Welche Regeln gibt es für C++ - Lambdas, um Verweise als Referenz zu erfassen?

int& TestClass::returnReference() 
{ 
     static int i=0; 
     return i; 
} 

std::function<void()> TestClass::testFunction() 
{ 
     int& memberRef = this->someIntMember; 
     int& intRef = returnReference(); 

     auto lambda = 
     [&] 
     { 
       // What happens when you capture a reference by reference 
       // like memberRef or intRef? 
     }; 

     return lambda; 
} 
+3

In Verbindung stehende [Erfassen einer Referenz durch Verweis in einem C++ 11 Lambda] (http://stackoverflow.com/questions/21443023/capturing-a-reference-by-reference-in-a-c11-lambda)? – sergej

+1

Ich denke (eigentlich, hoffe) die Absicht der Sprache ist, dass Sie einen Verweis auf das Objekt erhalten, dass die Referenzvariable bezieht sich, aber @ sergej Link macht mich wundern ... – molbdnilo

Antwort

6

Der Standard beauftragt es tatsächlich notwendig, um die Variable zu erfassen, nicht das, was es bezeichnet. Dies war ein Fehler im Standard und der einzige Fall in C++, in dem so etwas passieren konnte.

Es gibt eine defect report and suggested resolution (danke @ t.c.), Die es geändert hat, um die verwiesene Einigkeit zu erfassen.

Theoretisch gibt es eine kostengünstige Referenz-Capture-Technik, die den Stack-Pointer erfasst und Offsets verwendet, die am Punkt der Lambda-Deklaration bekannt sind (plus vielleicht this), die die Tatsache nutzen würden, dass wir nur eine Referenz durch Variable erfassen müssen nicht Inhalt. Aber kein Compiler, den ich kenne, hat ihn benutzt, und der Fehlerbericht impliziert, dass Referenzen, die Sie nicht in Locals/Globals umbenennen können, nicht auf diese Weise behandelt werden können.

Kurz gesagt, der Standard sagt das Falsche, aber es gibt kein praktisches Problem, da kein Compiler dem Buchstaben des Standards folgte, sondern eher das Richtige tat. Und zukünftige Compiler müssten gegen die vorgeschlagene Defektauflösung verstoßen, um das schlechte Verhalten zu haben.

+1

[CWG2011] (http: // wg21. link/CWG2011). –